JSP

概念

  • Java Server Pages:Java服务器端页面

    • 可以理解为:一个特殊的页面,其中既可以指定定义html标签,又可以定位java代码

    • 用于简化书写

1
2
3
4
5
6
7
8
9
<html>
<body>
<%
System.out.println("hello jsp");
%>

<h1>hi~ jsp!</h1>
</body>
</html>

浏览器显示
avatar
运行结果

1
hello jsp

快速入门

脚本

JSP定义Java代码的方式:

1
<% 代码 %>

定义的Java代码在service方法中。service方法中可以定义什么,该脚本就可以定义什么

1
<%! 代码 %>

定义的Java代码,在JSP转换后的Java类的成员位置。

1
<%= 代码 %>

定义的Java代码,会输出到页面上。输出语句中可以定义什么,该脚本中就可以定义什么

内置对象

  • 在JSP页面中不需要获取和创建,可以直接使用的对象

    • request

    • response

    • out:字符输出流对象。可以将数据输出到页面上,和response.getWriter()类似

      • response.getWriter()和out.write()的区别:在tomcat服务器真正给客户端做出响应之前,会找response缓冲区数据,再找out缓冲区数据
1
2
3
4
5
<%
System.out.println("hello jsp");
String contextPath = request.getContextPath();
out.print(contextPath);
%>

这样就可以在浏览器上输出虚拟地址,out和request就是内置对象

案例

首先创建一个叫showTime.jsp的文件

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
<%@ page import="java.util.Date" %>
<%@ page import="java.text.SimpleDateFormat" %>
<%@ page import="java.net.URLEncoder" %>
<%@ page import="java.net.URLDecoder" %><%--
Created by IntelliJ IDEA.
User: songf
Date: 2020/8/5
Time: 10:51
To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>itcast</title>
</head>
<body>

<%
//1.获取所有的cookie
Cookie[] cs = request.getCookies();
boolean flag=false; //没有cookie为false
//2.遍历cookie数组
if (cs!=null&&cs.length>0){
for (Cookie c : cs) {
//3.获取cookie的名称
String name = c.getName();
//4.判断名称是否是lastTime
if ("lastTime".equals(name)){
//有该cookie,不是第一次访问
flag=true;//有lastTime的cookie
//设置cookie的value
//获取当前时间的字符串,重新设置cookie的值,重新发送cookie
Date date=new Date();
SimpleDateFormat sdf=new SimpleDateFormat("yyyy年MM月dd日 HH:mm:ss");
String str_date = sdf.format(date);
System.out.println("编码前"+str_date);
//URL编码
str_date= URLEncoder.encode(str_date,"utf-8");
System.out.println("编码后"+str_date);
c.setValue(str_date);
//设置cookie的存活时间
c.setMaxAge(60*60*24*30);//一个月
response.addCookie(c);

//响应数据
//获取cookie的value,时间
String value = c.getValue();
System.out.println("解码前"+value);
//URL解码
value= URLDecoder.decode(value,"utf-8");
System.out.println("解码后"+value);
response.getWriter().write("欢迎回来,您上次访问时间为:"+value);

break;
}
}
}

if (cs==null || cs.length==0 || flag==false){
//没有,第一次访问

//设置cookie的value
//获取当前时间的字符串,重新设置cookie的值,重新发送cookie
Date date=new Date();
SimpleDateFormat sdf=new SimpleDateFormat("YYYY年MM月dd日 HH:mm:ss");
String str_date = sdf.format(date);
System.out.println("编码前"+str_date);
//URL编码
str_date=URLEncoder.encode(str_date,"utf-8");
System.out.println("编码后"+str_date);

Cookie c=new Cookie("lastTime", str_date);
c.setValue(str_date);
//设置cookie的存活时间
c.setMaxAge(60*60*24*30);//一个月
response.addCookie(c);

response.getWriter().write("您好,欢迎首次访问");
}


%>


</body>
</html>

直接将之前的代码复制过来,再次访问发现依旧是正常的,并且这样的操作还可以让你可以在后边添加上HTML代码

Session

概念

服务器端会话技术,在一次会话的多次请求见共享数据,将数据保存在服务器端的对象中。HttpSession

快速入门

  • 获取HttpSession对象

    • HttpSession session = request.getSession();
  • 使用HttpSession对象:

    • Object getAttribute(String name)

    • void setAttribute(String name,Object value)

    • void removeAttribute(String name)

session1

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
package cn.itcast.session;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.io.IOException;

public class sessionDemo1 extends HttpServlet {
@Override
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
//使用session共享数据

//1.获取session
HttpSession session = request.getSession();
//2.存储数据
session.setAttribute("msg","hello session");

}

@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
this.doPost(request, response);
}
}

session2

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
package cn.itcast.session;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.io.IOException;

public class sessionDemo2 extends HttpServlet {
@Override
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
//使用session共享数据

//1.获取session
HttpSession session = request.getSession();
//2.获取数据
Object msg = session.getAttribute("msg");
System.out.println(msg);

}

@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
this.doPost(request, response);
}
}

先访问session1,再访问session2
运行结果

1
hello session

关闭浏览器,再次访问session2
运行结果
1
null

这样就可以看到session的范围确实是一次会话内

Session是依赖于Cookie的

细节

  1. 当客户端关闭后,服务器不关闭,再次获取session是否为同一个?

  2. 客户端不关闭,服务器关闭后,两次获取的session是同一个吗?

  3. session的失效时间

问题1

默认情况下不是同一个,因为关闭再开启之后,相当于重新开启了一个会话

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25

package cn.itcast.session;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.io.IOException;

public class sessionDemo3 extends HttpServlet {
@Override
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
//1.获取session
HttpSession session = request.getSession();

System.out.println(session);

}

@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
this.doPost(request, response);
}
}

先访问第一次,运行结果
1
org.apache.catalina.session.StandardSessionFacade@5d1eba7c

关闭浏览器再次访问,运行结果
1
org.apache.catalina.session.StandardSessionFacade@610f36ce

可以看到明显的不同,这就说明了当客户端关闭后,服务器不关闭,再次获取session不是为同一个

如果想客户端关闭后,session也相同,就可以改为

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
package cn.itcast.session;

import javax.servlet.ServletException;
import javax.servlet.http.*;
import java.io.IOException;

public class sessionDemo3 extends HttpServlet {
@Override
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
//1.获取session
HttpSession session = request.getSession();

//客户端关闭后,session也相同
Cookie c=new Cookie("JSESSIONID", session.getId());
c.setMaxAge(60*60);
response.addCookie(c);

System.out.println(session);
}

@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
this.doPost(request, response);
}
}

运行结果
1
org.apache.catalina.session.StandardSessionFacade@728cb723

关闭浏览器重新访问
1
org.apache.catalina.session.StandardSessionFacade@728cb723

发现两个一样,这就是上面说的session是依赖于cookie的,设置cookie的存活时间就可以设置session

问题2

  • 不是同一个,但是要确保数据不丢失

    • session的钝化:

      • 在服务器正常关闭之前,将session对象序列化到硬盘上
    • session的活化:

      • 在服务器启动后,将session文件转化为内存中的session对象即可

问题3

关闭原因:

  1. 服务器关闭

  2. session对象调用方法invalidate()

  3. session默认失效时间为30分钟

在tomcat的配置文件中web.xml可以设置session的默认失效时间,可以字节修改

特点

  1. session是用于存储一次会话的多次请求的数据,存在服务器端

  2. session可以存储任意类型,任意大小的数据

  • session与cookie的区别:

    1. session存储数据在服务器端,cookie在客户端

    2. session没有数据大小限制,cookie有

    3. session数据安全,cookie相对不安全