- Session是重点,今后学习分布式、redis、第三方缓存服务器里依然会用到。
- 服务器会给每个客户端创建一个Session对象(不同的浏览器也会创造不同的Session)。
- 用户登陆之后,所有子网站都能识别这个Session对象。
cookie和Session的区别 - 相对于cookie,session
新建一个类名为SessionDemo01,内容如下:
public class SessionDemo01 extends HttpServlet {
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//照例先解决乱码问题
resp.setCharacterEncoding("utf-8");
req.setCharacterEncoding("utf-8");
resp.setContentType("text/html;charset=utf-8");
//得到Session
HttpSession session = req.getSession();
//往Session存东西
session.setAttribute("name","Ju");
//获取Session的ID
String Sessionid = session.getId();
//判断是不是新的Session
if (session.isNew()){
resp.getWriter().write("Session创建成功,ID为: " + Sessionid);
}else {
resp.getWriter().write("Session已经存在,ID为: " + Sessionid);
}
}
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
doPost(req, resp);
}
}
注册Servlet:
cookieDemo01 com.sunsplanter.servlet.cookieDemo01 cookieDemo01 /cookie
运行后发现页面显示Session已经在服务器中存在,审查元素Application发现SessionId存放在cookie中,Network发现s1的请求头中有SessionId
因为实际上new一个Session的时候,系统做了一件这样的事情:
cookie cookie = new cookie("JSESSIONID",sessionId);
resp.addcookie(cookie);
可以看出Session和cookie还是很类似的。
换浏览器输入同样的网址,Session的id会不一样,但同一个浏览器内多个标签页的id都会一样。
新建一个类名为SessionDemo02,内容如下:
public class SessionDemo02 extends HttpServlet {
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//照例先解决乱码问题
resp.setCharacterEncoding("utf-8");
req.setCharacterEncoding("utf-8");
resp.setContentType("text/html;charset=utf-8");
//得到Session
HttpSession session = req.getSession();
String name = (String)session.getAttribute("name");
System.out.println(name);
}
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
doPost(req, resp);
}
}
注册Servlet如下:
SessionDemo02 com.sunsplanter.servlet.SessionDemo02 SessionDemo02 /s2
运行后先进入s1,存入一个session(包括id和内容),再进入s2,idea的控制台中会输出name的值。
既然Session能取到字符串,当然也可以取到对象。
在sunsplanter下新建一个包名为pojo,pojo包下新建一个类名为Person,内容如下:
public class Person {
private String name;
private int age;
public Person() {
}
public Person(String name, int age) {
this.name = name;
this.age = age;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
//为了调试方便重写toString,为了安全还可以重写hashCode等方法
@Override
public String toString() {
return "Person{" +
"name='" + name + ''' +
", age=" + age +
'}';
}
}
SessionDemo01中往Session存内容的语句修改为:
//往Session存东西
session.setAttribute("person1",new Person("Ju",20));
SessionDemo02中得到Session的语句修改为:
//得到Session
HttpSession session = req.getSession();
Person person1 = (Person) session.getAttribute("person1");
System.out.println(person1.toString());
运行后先进入后缀s1存person1,再进入后缀s2,控制台会输出:
我们之前谈过,跨Servlet共享数据要依靠ServletContext,但现在学习了Session,可以依靠Session实现同样的事情,ServletContext存的东西多了服务器压力大,尽量别使用。
新建一个类名为SessionDemo03,内容为
public class SessionDemo03 extends HttpServlet {
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//照例先解决乱码问题
resp.setCharacterEncoding("utf-8");
req.setCharacterEncoding("utf-8");
resp.setContentType("text/html;charset=utf-8");
HttpSession session = req.getSession();
session.removeAttribute("person1");
session.invalidate();
}
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
doPost(req, resp);
}
}
注册servlet如下:
SessionDemo03 com.sunsplanter.servlet.SessionDemo03 SessionDemo03 /s3
运行后先进入后缀s1存入Session内容,再进入s3注销Session,此时进入s2会报500错误,因为Session已经不存在。
也可以设置让服务器自动注销,方法是在web.xml中设置Session过期时间,如下:
15
自动失效和手动失效可以同时存在已达到项目的要求,注意的的一点是如果自动过期时间过长,服务器上Session信息过多会导致服务器压力过大。如果想要长时间保存,可以使用cookie,因为cookie是保存在客户端的不会占用服务器资源。与此同时,一些重要的数据例如:登录用户的信息、经常使用的信息,应该保存在服务器中,避免服务器资源的浪费。



