Session, Cookie及交互

会话(Session)跟踪是Web程序中常用的技术,用来跟踪用户的整个会话。常用的会话跟踪技术是Cookie与Session。

Cookie通过在客户端记录信息确定用户身份,Session通过在服务器端记录信息确定用户身份。

HTTP 是一种"无状态"协议,这意味着每次客户端检索网页时,客户端打开一个单独的连接到 Web 服务器,服务器会自动不保留之前客户端请求的任何记录。

但是仍然有以下三种方式来维持 Web 客户端和 Web 服务器之间的 session 会话:

Cookies:Session创建成功以后,会创建Cookie(key='JSESSIONID', value=Session ID)。通常情况下,一个浏览器的多个Tag可以共享一个Session对象。

隐藏的表单字段(Form适用):有些浏览器不支持Cookie,可以用表单隐藏域代替。

<input type="hidden" name="sessionid" value="12345">

URL 重写(Link适用):如果使用URL提交时,可以作为URL参数传递。

http://localhost:8080/ServletTest/login?sessionid=12345

下面是一个使用Cookie来维持Session会话的例子。重点代码讲解在例子中。

 package com.servlettest.session;

 import java.io.IOException;
import java.io.PrintWriter; 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; /**
* Servlet implementation class Login
*/
@WebServlet("/default")
public class Default extends HttpServlet { private static final long serialVersionUID = 1L; /**
* @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse response)
*/
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException { invalidateSession(request); response.setContentType("text/html");
request.setCharacterEncoding("UTF-8");
response.setCharacterEncoding("UTF-8"); PrintWriter out = response.getWriter();
out.println("<!DOCTYPE html>");
out.println("<html>");
out.println("<head>");
out.println("<title>Login Page</title>");
out.println("</head>");
out.println("<body>");
out.println("<form action=\"login\" method=\"POST\">");
out.println("帐号: <input type=\"text\" name=\"userId\"/><br/>");
out.println("密码: <input type=\"password\" name=\"password\"/><br/>");
out.println("<input type=\"submit\" value=\"提交\"/>"); // HttpServletRequest Attribute和Parameter的区别
// (1) HttpServletRequest 类有setAttribute()方法,而没有setParameter()方法。
// (2) 当两个Web组件之间为链接关系时,被链接的组件通过getParameter()方法来获得请求参数,一般通过表单和链接传递的参数使用getParameter。
// (3) 当两个Web组件之间为转发关系时,转发目标组件通过getAttribute()方法来和转发源组件共享request范围内的数据。
String message = (String) request.getAttribute("message");
if (message != null && message != "") {
out.println("<p>" + message + "</p>");
}
out.println("</body>");
out.println("</html>");
} /**
* @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse response)
*/
@Override
protected void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
doGet(request, response);
} private static void invalidateSession(HttpServletRequest request) {
HttpSession session = request.getSession(false);
if (session != null)
session.invalidate();
}
}
 package com.servlettest.session;

 import java.io.IOException;
import java.util.HashMap;
import java.util.Map; 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; /**
* Servlet implementation class Login
*/
@WebServlet("/login")
public class Login extends HttpServlet { private static final long serialVersionUID = 1L; private static final Map<String, String[]> USER_INFO = initUserInfo(); /**
* @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse response)
*/
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException { response.setContentType("text/html"); request.setCharacterEncoding("UTF-8");
response.setCharacterEncoding("UTF-8"); // 获取用户登录信息
String userId = request.getParameter("userId");
String password = request.getParameter("password");
if ((userId == null || userId == "") || (password == null || password == "")) {
request.getRequestDispatcher("/default").forward(request, response);
} else if (USER_INFO.containsKey(userId)) {
String[] info = USER_INFO.get(userId);
if (info[1].equals(password)) {
// 创建Session
setSession(userId, info[0], request, response);
request.getRequestDispatcher("/welcome1").forward(request, response);
} else {
request.setAttribute("message", "帐号或密码错误!");
request.getRequestDispatcher("/default").forward(request, response);
}
} else {
request.setAttribute("message", "帐号或密码错误!");
request.getRequestDispatcher("/default").forward(request, response);
}
} /**
* @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse response)
*/
@Override
protected void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
doGet(request, response);
} private static Map<String, String[]> initUserInfo() { Map<String, String[]> result = new HashMap<>();
String[] user1 = { "张三", "123" };
result.put("101", user1);
String[] user2 = { "李四", "456" };
result.put("102", user2);
String[] user3 = { "王五", "789" };
result.put("103", user3); return result;
} private void setSession(String userId, String userName, HttpServletRequest request, HttpServletResponse response) {
// 如果不存在 session 会话,则创建一个 session 对象
HttpSession session = request.getSession(true);
String[] userInfo = { userId, userName };
session.setAttribute("USER_INFO", userInfo);
}
}
 package com.servlettest.session;

 import java.io.IOException;
import java.io.PrintWriter;
import java.util.Enumeration; 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; /**
* Servlet implementation class Welcome
*/
@WebServlet("/welcome1")
public class Welcome1 extends HttpServlet { private static final long serialVersionUID = 1L; /**
* @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse response)
*/
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException { response.setContentType("text/html");
request.setCharacterEncoding("UTF-8");
response.setCharacterEncoding("UTF-8"); // 注意request.getSession() 等同于 request.getSession(true),除非我们确认session一定存在或者sesson不存在时明确有创建session的需要,否则请尽量使用request.getSession(false)
HttpSession session = request.getSession(false);
String[] userInfo = (String[]) session.getAttribute("USER_INFO");
PrintWriter out = response.getWriter();
out.println("<!DOCTYPE html>");
out.println("<html>");
out.println("<head>");
out.println("<title>Login Page</title>");
out.println("</head>");
out.println("<body>");
out.println("您好 <b>" + userInfo[0] + "-" + userInfo[1] + "</b>, 这是Welcome1画面!");
out.println("<br/><a href = \"welcome2\">去welcome2</a> | <a href = \"default\">注销</a>");
out.println("<br/>");
out.println("<p>SessionID: " + session.getId() + "</p>");
Enumeration<String> names = session.getAttributeNames();
while (names.hasMoreElements()) {
String name = names.nextElement();
out.println("<p>" + names.nextElement() + ": " + session.getAttribute(name) + "</p>");
}
out.println("</table>");
out.println("</body>");
out.println("</html>");
out.close();
} /**
* @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse response)
*/
@Override
protected void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
doGet(request, response);
}
}
 package com.servlettest.session;

 import java.io.IOException;
import java.io.PrintWriter;
import java.util.Enumeration; 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; /**
* Servlet implementation class Welcome
*/
@WebServlet("/welcome2")
public class Welcome2 extends HttpServlet { private static final long serialVersionUID = 1L; /**
* @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse response)
*/
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException { response.setContentType("text/html");
request.setCharacterEncoding("UTF-8");
response.setCharacterEncoding("UTF-8"); // 注意request.getSession() 等同于 request.getSession(true),除非我们确认session一定存在或者sesson不存在时明确有创建session的需要,否则请尽量使用request.getSession(false)
HttpSession session = request.getSession(false);
String[] userInfo = (String[]) session.getAttribute("USER_INFO");
PrintWriter out = response.getWriter();
out.println("<!DOCTYPE html>");
out.println("<html>");
out.println("<head>");
out.println("<title>Login Page</title>");
out.println("</head>");
out.println("<body>");
out.println("您好 <b>" + userInfo[0] + "-" + userInfo[1] + "</b>, 这是Welcome2画面!");
out.println("<br/><a href = \"welcome1\">去welcome1</a> | <a href = \"default\">注销</a>");
out.println("<br/>");
out.println("<p>SessionID: " + session.getId() + "</p>");
Enumeration<String> names = session.getAttributeNames();
while (names.hasMoreElements()) {
String name = names.nextElement();
out.println("<p>" + names.nextElement() + ": " + session.getAttribute(name) + "</p>");
}
out.println("</body>");
out.println("</html>");
out.close();
} /**
* @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse response)
*/
@Override
protected void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
doGet(request, response);
}
}
 package com.servlettest.filter;

 import java.io.IOException;
import java.util.ArrayList;
import java.util.List; import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession; import com.servlettest.exception.PermissionException; public class PermissionFilter implements Filter { private final static List<String> URL = new ArrayList<>(); @Override
public void init(FilterConfig arg0) throws ServletException {
URL.add("/ServletTest/welcome1");
URL.add("/ServletTest/welcome2");
} @Override
public void doFilter(ServletRequest arg0, ServletResponse arg1, FilterChain arg2)
throws IOException, ServletException {
if (arg0 instanceof HttpServletRequest && arg1 instanceof HttpServletResponse) {
HttpServletRequest req = (HttpServletRequest) arg0;
if (URL.contains(req.getRequestURI())) {
HttpSession session = req.getSession(true);
String[] userInfo = (String[]) session.getAttribute("USER_INFO");
if (userInfo == null) {
throw new PermissionException();
}
}
}
arg2.doFilter(arg0, arg1);
} @Override
public void destroy() {
}
}
 package com.servlettest.exception;

 public class PermissionException extends RuntimeException {

     private static final long serialVersionUID = 1L;

 }
 <!DOCTYPE html>
<html>
<head>
<meta charset="utf-8"/>
<title>Forbidden</title>
</head>
<body>
<h2>403 禁止访问所请求的页面</h2>
</body>
</html>
 <?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://xmlns.jcp.org/xml/ns/javaee"
xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd"
id="WebApp_ID" version="3.1">
<filter>
<filter-name>permissionFilter</filter-name>
<filter-class>com.servlettest.filter.PermissionFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>permissionFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
<error-page>
<error-code>403</error-code>
<location>/html/forbidden.html</location>
</error-page>
<error-page>
<exception-type>com.servlettest.exception.PermissionException</exception-type>
<location>/html/forbidden.html</location>
</error-page>
<welcome-file-list>
<welcome-file>default</welcome-file>
</welcome-file-list>
<session-config>
<session-timeout>1</session-timeout>
</session-config>
</web-app>

Servlet(4):Session的更多相关文章

  1. Servlet和JSP学习指导与实践(二):Session追踪

    前言: web应用中经常需要对某些有用的信息进行存储或者附加一些信息.本文主要介绍session,即“会话”跟踪的几种不同方式~ ----------------------------4种管理ses ...

  2. Servlet(七):session

    Session 学习:问题: Request 对象解决了一次请求内的不同 Servlet 的数据共享问 题,那么一个用户的不同请求的处理需要使用相同的数据怎么办呢?解决: 使用 session 技术. ...

  3. Servlet(3):Cookie和Session

    一. Cookie Cookie是客户端技术,程序把每个用户的数据以cookie的形式写给用户各自的浏览器.当用户使用浏览器再去访问服务器中的web资源时,就会带着各自的数据去.这样,web资源处理的 ...

  4. servlet会话技术:Session

    问题的引出 1.在网上购物时,张三和李四购买的商品不一样,他们的购物车中显示的商品也不一样,这是怎么实现的呢? 2.不同的用户登录网站后,不管该用户浏览该网站的那个页面,都可以显示登录人的名字,同时可 ...

  5. 【转】java:Session(会话)机制详解

    书中讲:以下情况,Session结束生命周期,Servlet容器将Session所占资源释放:1.客户端关闭浏览器2.Session过期3.服务器端调用了HttpSession的invalidate( ...

  6. 面试题:servlet jsp cook session 背1

    一.Servlet是什么?JSP是什么?它们的联系与区别是什么? Servlet是Java编写的运行在Servlet容器的服务端程序,狭义的Servlet是指Servlet接口,广义的Servlet是 ...

  7. [原创]java WEB学习笔记33:Session 案例 之 购物车

    本博客为原创:综合 尚硅谷(http://www.atguigu.com)的系统教程(深表感谢)和 网络上的现有资源(博客,文档,图书等),资源的出处我会标明 本博客的目的:①总结自己的学习过程,相当 ...

  8. Java Web之Servlet及Cookie/Session

    Servlet参考文献: 1.http://www.cnblogs.com/luoxn28/p/5460073.html 2.http://www.cnblogs.com/xdp-gacl/p/376 ...

  9. MZY项目笔记:session歧路

    from my typora MZY项目笔记:session歧路 文章目录 MZY项目笔记:session歧路 那该怎么办? 1. 手动加上cookie的header. 2.自己模拟一个Session ...

随机推荐

  1. NOIP2016 Day1 T2 天天爱跑步(树上差分,LCA)

    原文链接 原题链接 题目描述 小c同学认为跑步非常有趣,于是决定制作一款叫做<天天爱跑步>的游戏.<天天爱跑步>是一个养成类游戏,需要玩家每天按时上线,完成打卡任务. 这个游戏 ...

  2. The Tower HDU - 6559 (解析几何)

    The Tower HDU - 6559 The Tower shows a tall tower perched on the top of a rocky mountain. Lightning ...

  3. mybatis配置加载源码概述

    Mybatis框架里,有两种配置文件,一个是全局配置文件config.xml,另一个是对应每个表的mapper.xml配置文件.Mybatis框架启动时,先加载config.xml, 在加载每个map ...

  4. Linux之RPM 软件管理程序

    RPM RPM是软件管理程序,提供软件的安装.升级.查询.反安装的功能.优点:a.安装方便,软件中所有数据都经过编译和打包b.查询.升级.反安装方便缺点:a.缺乏灵活性b.存在相依属性 用法: rpm ...

  5. python高级特征:列表生成式;generator, 迭代器。

    Python高级特性 列表生成式:不过一种语法糖 生成器:不过一个方法 迭代器: 列表生成式 Python内置的函数,来创建list. 简单的生成: >>> list(range(1 ...

  6. linux内核 进程调度

    概念: 进程调度决定那个进程投入运行,运行多长时间. 进程调度没有太复杂的原理,最大限度的利用处理器时间的原则是:只要有可执行的程序,那么总会有进程在执行,如果可运行的进程比处理器数目要多,那么注定要 ...

  7. loj2314 「NOIP2017」小凯的疑惑[同余最短路or数论]

    这题以前就被灌输了“打表找规律”的思想,所以一直没有好好想这道题,过了一年还不太会qwq.虽然好像确实很简单,但是还是带着感觉会被嘲讽的心态写这个题解...而且还有一个log做法不会... 法1:(一 ...

  8. 【bug解决】ios微信浏览器中背景音乐无法播放

    我记得之前在一次项目中,出现过浏览报错: 当时的文档链接如右:[解决]HTML5新标签audio的autoplay自动播放属性失效的解决方案 所以在这次H5的制作中,我使用了iframe来加载音频文件 ...

  9. php+提高大文件上传速度

    PHP用超级全局变量数组$_FILES来记录文件上传相关信息的. 1.file_uploads=on/off 是否允许通过http方式上传文件 2.max_execution_time=30 允许脚本 ...

  10. codevs 2010 求后序遍历x

    题目描述 Description 输入一棵二叉树的先序和中序遍历序列,输出其后序遍历序列. 输入描述 Input Description 共两行,第一行一个字符串,表示树的先序遍历,第二行一个字符串, ...