Session是服务器端的会话技术,用户通过浏览器访问服务器时,服务器会给每个浏览器创建一个session,用于保存用户的信息。
package test.session;
import java.io.IOException;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
public class SessionDemo5 extends HttpServlet {
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
// 获取Session,也就是创建一个Session
HttpSession hs = request.getSession();
// 保存数据到session中
hs.setAttribute("data", "data");
// 获取session编号
String sid = hs.getId();
// 判断是否为新创建的session
if(hs.isNew()){
response.getOutputStream().write(("创建一个session,其id为 "+sid).getBytes());
}else {
response.getOutputStream().write(("已创建session,其id为 "+sid).getBytes());
}
}
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
doGet(request, response);
}
}
第一次访问该servlet时,显示:
然后点击刷新按钮,显示:
发现两次的id值是相同的。再查看浏览器的cookie信息:
在servlet代码的else中加入打印该Cookie的程序:
if(hs.isNew()){
response.getOutputStream().write(("创建一个session,其id为 "+sid).getBytes());
}else {
response.getOutputStream().write(("已创建session,其id为 "+sid).getBytes());
// 打印名为Jseesionid的cookie信息
Cookie[] cs = request.getCookies();
if(cs != null){
for(Cookie c : cs){
if(c.getName().equals("JSESSIONID")){
response.getOutputStream().write((" JSESSIONID is "+c.getValue()).getBytes());
}
}
}
}
发现cookie中的jsessionid的值和session的id编号相同。
由此可以推断出:在创建一个新的session时,服务器还做了额外的操作:获取session的id,然后将他存储到一个名为JSESSIONID的cookie中,返还给浏览器。在接下来的访问中,浏览器会带着这个cookie去访问服务器。
1、创建
在程序第一次执行request对象的getSession方法时,会创建一个Session对象
// 使用request对象的getSession方法,得到一个session,如果不存在就创建一个
HttpSession session = request.getSession();
2、销毁
销毁分为自然销毁和手动销毁。
自然销毁:session的默认保存时间为30分钟,到时间后服务器会自动销毁。也可以在web.xml文件中配置session的销毁时间。
<web-app version="2.5"
xmlns="http://java.sun.com/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee
http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd">
<display-name>display-name>
<welcome-file-list>
<welcome-file>index.jspwelcome-file>
welcome-file-list>
<session-config>
<session-timeout>15session-timeout>
session-config>
web-app>
手动销毁:调用session.invalidate方法,销毁session。
HttpSession session = request.getSession();
//手工调用session.invalidate方法,摧毁session
session.invalidate();
通过session的原理分析可以知道,session在创建的时候会给浏览器一个名为JSESSIONID的cookie,通过这个cookie我们在下次访问时,会带上这个cookie信息,被服务器识别。如果禁用了浏览器的cookie,那么就不会有这种效果了。
如果想实现禁用cookie后的效果和没有禁用之前的效果相同。那么我们可以使用URL重写。
URL重写:
response.encodeRedirectURL(java.lang.String url) 用于对sendRedirect方法后的url地址进行重写。
response.encodeURL(java.lang.String url)用于对表单action和超链接的url地址进行重写
实例:
IndexServlet
import java.io.IOException;
import java.io.PrintWriter;
import java.util.LinkedHashMap;
import java.util.Map;
import java.util.Set;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
//首页:列出所有书
public class IndexServlet extends HttpServlet {
public void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
response.setContentType("text/html;charset=UTF-8");
PrintWriter out = response.getWriter();
//创建Session
request.getSession();
out.write("本网站有如下书:
");
Set> set = DB.getAll().entrySet();
for(Map.Entry me : set){
Book book = me.getValue();
String url =request.getContextPath()+ "/servlet/BuyServlet?id=" + book.getId();
//response. encodeURL(java.lang.String url)用于对表单action和超链接的url地址进行重写
url = response.encodeURL(url);//将超链接的url地址进行重写
out.println(book.getName() + " 购买
");
}
}
public void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
doGet(request, response);
}
}
// 模拟数据库
class DB{
// 使用LinkedHashMap,方便遍历,并且数据有序
private static Map map = new LinkedHashMap();
static{
map.put("1", new Book("1","javaweb开发"));
map.put("2", new Book("2","spring开发"));
map.put("3", new Book("3","hibernate开发"));
map.put("4", new Book("4","struts开发"));
map.put("5", new Book("5","ajax开发"));
}
public static Map getAll(){
return map;
}
}
class Book{
private String id;
private String name;
public Book() {
super();
}
public Book(String id, String name) {
super();
this.id = id;
this.name = name;
}
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
BuyServlet
package xdp.gacl.session;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
// 将买的数添加到session中
public class BuyServlet extends HttpServlet {
public void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
//得到用户想买的书
String id = request.getParameter("id");
Book book = DB.getAll().get(id);
//得到用户用于保存所有书的容器
HttpSession session = request.getSession();
List list = (List) session.getAttribute("list");
// 第一次创建一个list集合
if(list==null){
list = new ArrayList();
session.setAttribute("list", list);
}
list.add(book);
//response. encodeRedirectURL(java.lang.String url)用于对sendRedirect方法后的url地址进行重写
String url = response.encodeRedirectURL(request.getContextPath()+"/servlet/ListCartServlet");
System.out.println(url);
response.sendRedirect(url);
}
public void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
doGet(request, response);
}
}
ListCartServlet
package xdp.gacl.session;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.List;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
public class ListCartServlet extends HttpServlet {
public void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
response.setContentType("text/html;charset=UTF-8");
PrintWriter out = response.getWriter();
HttpSession session = request.getSession();
List list = (List) session.getAttribute("list");
if(list==null || list.size()==0){
out.write("对不起,您还没有购买任何商品!!");
return;
}
//显示用户买过的商品
out.write("您买过如下商品:
");
for(Book book : list){
out.write(book.getName() + "
");
}
}
public void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
doGet(request, response);
}
}
在禁用了cookie的IE8下的运行效果如下:
通过查看IndexServlet生成的html代码可以看到,每一个超链接后面都带上了session的Id,如下所示
本网站有如下书:<br/>javaweb开发 <a href='/JavaWeb_Session_Study_20140720/servlet/BuyServlet;jsessionid=96BDFB9D87A08D5AB1EAA2537CDE2DB2?id=1'>购买a><br/>
spring开发 <a href='/JavaWeb_Session_Study_20140720/servlet/BuyServlet;jsessionid=96BDFB9D87A08D5AB1EAA2537CDE2DB2?id=2'>购买a><br/>
hibernate开发 <a href='/JavaWeb_Session_Study_20140720/servlet/BuyServlet;jsessionid=96BDFB9D87A08D5AB1EAA2537CDE2DB2?id=3'>购买a><br/>
struts开发 <a href='/JavaWeb_Session_Study_20140720/servlet/BuyServlet;jsessionid=96BDFB9D87A08D5AB1EAA2537CDE2DB2?id=4'>购买a><br/>
ajax开发 <a href='/JavaWeb_Session_Study_20140720/servlet/BuyServlet;jsessionid=96BDFB9D87A08D5AB1EAA2537CDE2DB2?id=5'>购买a><br/>
另外,esponse. encodeRedirectURL(java.lang.String url) 和response. encodeURL(java.lang.String url)是两个非常智能的方法,当检测到浏览器没有禁用cookie时,那么就不进行URL重写了。
部分引用自:http://www.cnblogs.com/xdp-gacl/p/3855702.html