目录
一、引言:
1.1 什么是会话?
会话,用户在打开浏览器访问web服务器资源的时候会话会建立,直到有一方断开连接,会话结束,在一次的会话中可以含多次请求和响应
1.2 什么是会话跟踪?
会话跟踪,是一种维护浏览器状态的方法,服务器需要识别多次请求是否来自于同一浏览器,以便在同一次的会话的多次请求访问间可以进行数据的共享,比如加入购物车、展示登录名、验证码的验证操作等都需要会话跟踪技术的支持
1.3 为什么要使用会话跟踪技术?
由于Http协议是无状态的,每次浏览器向服务器发送请求的时候,都将视为新的请求,因此我们需要会话跟踪技术来实现会话内的数据共享
1.4 会话跟踪技术的实现方式有哪些?
- 客户端会话跟踪技术:Cookie
- 服务器会话追踪技术:Session
二、Cookie:
2.1 Cookie的基本使用
Cookie是客户端会话追踪技术,将数据保存到客户端,以后每次请求都携带Cookie数据进行访问,其基本使用可分为以下的五部分;
- 创建Cookie对象,设置数据
package Cookie; import javax.servlet.annotation.WebServlet; import javax.servlet.http.Cookie; @WebServlet("/CookieServlet01") public class CookieServlet extends javax.servlet.http.HttpServlet { @Override protected void doGet(javax.servlet.http.HttpServletRequest request, javax.servlet.http.HttpServletResponse response) throws javax.servlet.ServletException, java.io.IOException { System.out.println("--------------CookieServlet01"); String UserName = "zhahngsan"; // 创建Cookie对象,键为username,值为字符类型的UserName Cookie cookie = new Cookie("username",UserName); } @Override protected void doPost(javax.servlet.http.HttpServletRequest request, javax.servlet.http.HttpServletResponse response) throws javax.servlet.ServletException, java.io.IOException { this.doGet(request, response); } }
- 发送Cookie到客户端(使用response对象)
package Cookie; import javax.servlet.annotation.WebServlet; import javax.servlet.http.Cookie; @WebServlet("/CookieServlet01") public class CookieServlet extends javax.servlet.http.HttpServlet { @Override protected void doGet(javax.servlet.http.HttpServletRequest request, javax.servlet.http.HttpServletResponse response) throws javax.servlet.ServletException, java.io.IOException { System.out.println("--------------CookieServlet01"); String UserName = "zhahngsan"; // 创建Cookie对象 Cookie cookie = new Cookie("username",UserName); // 发送Cookie到客户端 response.addCookie(cookie); } @Override protected void doPost(javax.servlet.http.HttpServletRequest request, javax.servlet.http.HttpServletResponse response) throws javax.servlet.ServletException, java.io.IOException { this.doGet(request, response); } }
- 获取客户端携带的所有cookie(使用request对象)
package Cookie; import javax.servlet.annotation.WebServlet; import javax.servlet.http.Cookie; @WebServlet("/CookieServlet02") public class CookieServlet02 extends javax.servlet.http.HttpServlet { @Override protected void doGet(javax.servlet.http.HttpServletRequest request, javax.servlet.http.HttpServletResponse response) throws javax.servlet.ServletException, java.io.IOException { System.out.println("--------------CookieServlet02"); // 获取客户端携带的所有cookie,返回的是一个集合 Cookie[] cookies = request.getCookies(); } @Override protected void doPost(javax.servlet.http.HttpServletRequest request, javax.servlet.http.HttpServletResponse response) throws javax.servlet.ServletException, java.io.IOException { this.doGet(request, response); } }
- 遍历数组,获取每一个cookie对象
package Cookie; import javax.servlet.annotation.WebServlet; import javax.servlet.http.Cookie; @WebServlet("/CookieServlet02") public class CookieServlet02 extends javax.servlet.http.HttpServlet { @Override protected void doGet(javax.servlet.http.HttpServletRequest request, javax.servlet.http.HttpServletResponse response) throws javax.servlet.ServletException, java.io.IOException { System.out.println("--------------CookieServlet02"); // 获取客户端携带的所有cookie Cookie[] cookies = request.getCookies(); //遍历cookie对象 for (Cookie c:cookies ) { } } @Override protected void doPost(javax.servlet.http.HttpServletRequest request, javax.servlet.http.HttpServletResponse response) throws javax.servlet.ServletException, java.io.IOException { this.doGet(request, response); } }
- 使用cookie对象获取数据
package Cookie; import javax.servlet.annotation.WebServlet; import javax.servlet.http.Cookie; @WebServlet("/CookieServlet02") public class CookieServlet02 extends javax.servlet.http.HttpServlet { @Override protected void doGet(javax.servlet.http.HttpServletRequest request, javax.servlet.http.HttpServletResponse response) throws javax.servlet.ServletException, java.io.IOException { System.out.println("--------------CookieServlet02"); // 获取客户端携带的所有cookie Cookie[] cookies = request.getCookies(); for (Cookie c:cookies ) { //根据键获取值 String key =c.getName() ; if (key.equals("username")){ System.out.println(c.getValue()); } } } @Override protected void doPost(javax.servlet.http.HttpServletRequest request, javax.servlet.http.HttpServletResponse response) throws javax.servlet.ServletException, java.io.IOException { this.doGet(request, response); } }
运行tomcat服务器,在地址栏输入 http://localhost:8080/CookieServlet01,会在控制台进行提示信息的提示,此时Cookie会被创建,再在地址栏输入http://localhost:8080/CookieServlet02,此时再次查看控制台信息,会发现‘username’已经传递过来了
2.2 Cookie的实现原理:
Cookie的实现是基于HTTP协议的
- 响应头 :Set-Cookie
- 请求头: Cookie
2.4 cookie如何解决存储中文的问题
在上面的示例中,我们进行Cookie的基本操作,但是当我们传递的值是中文“张三”时,会不会和传递“zhangsan”的时候一样顺利呢?小编根据不同版本的tomcat进行了不同的测试,得到的结果是不同的,tomcat8以上的版本是可以传递的,但是较低的tomcat是会报错的。解决措施如下:
1、在存储的时候进行转码
package Cookie;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.Cookie;
import java.net.URLEncoder;
@WebServlet("/CookieServlet01")
public class CookieServlet extends javax.servlet.http.HttpServlet {
@Override
protected void doGet(javax.servlet.http.HttpServletRequest request, javax.servlet.http.HttpServletResponse response) throws javax.servlet.ServletException, java.io.IOException {
System.out.println("--------------CookieServlet01");
String UserName = "张三";
// 进行url转码
UserName = URLEncoder.encode(UserName,"utf-8");
// 创建Cookie对象
Cookie cookie = new Cookie("username",UserName);
// 发送Cookie到客户端
response.addCookie(cookie);
}
@Override
protected void doPost(javax.servlet.http.HttpServletRequest request, javax.servlet.http.HttpServletResponse response) throws javax.servlet.ServletException, java.io.IOException {
this.doGet(request, response);
}
}
2、在获取数据的时候进行解码
package Cookie;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.Cookie;
import java.net.URLDecoder;
@WebServlet("/CookieServlet02")
public class CookieServlet02 extends javax.servlet.http.HttpServlet {
@Override
protected void doGet(javax.servlet.http.HttpServletRequest request, javax.servlet.http.HttpServletResponse response) throws javax.servlet.ServletException, java.io.IOException {
System.out.println("--------------CookieServlet02");
// 获取客户端携带的所有cookie
Cookie[] cookies = request.getCookies();
for (Cookie c:cookies
) {
String key =c.getName() ;
if (key.equals("username")){
String value = c.getValue();
// 进行转码
value = URLDecoder.decode(value,"utf-8");
System.out.println(value);
}
}
}
@Override
protected void doPost(javax.servlet.http.HttpServletRequest request, javax.servlet.http.HttpServletResponse response) throws javax.servlet.ServletException, java.io.IOException {
this.doGet(request, response);
}
}
即可解决存储中文的问题~~~
三、Session:
3.1 Session基本使用
HttpSession session = request.getSession(); |
Void SetAttribute(String name,Object o):存储数据到Session域中 |
Object getAttribute(String Name): 根据key,获取值 |
Void RemoveAttribute(String Name):根据key,删除该键值对 |
3.2 Session的实现原理
Session是基于Cookie实现的(在一次会话中多次请求,获取的是同一Session)
3.3 Session的使用细节(Session钝化、活化)
Session钝化:在服务器正常关闭后,Tomcat会自动将Session数据写入硬盘文件中
Session活化:再次启动服务器后,从文件中加载数据到Session中
Session钝化、活化可以实现服务器重启后,Session中的数据依然存在
3.4 Session的销毁两种方式
1、默认情况下,无操作,30分钟后自动销毁,可以等待Session自动销毁
<!DOCTYPE web-app PUBLIC
"-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN"
"http://java.sun.com/dtd/web-app_2_3.dtd" >
<web-app>
<display-name>Archetype Created Web Application</display-name>
<session-config>
<session-timeout>30</session-timeout>
</session-config>
</web-app>
2、调用Session对象的invalidate()方法进行销毁
package Session;
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;
import java.io.IOException;
@WebServlet("/Session02")
public class Session02 extends HttpServlet {
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
HttpSession session = request.getSession();
Object name = session.getAttribute("name");
System.out.println(name);
// 销毁
session.invalidate();
}
@Override
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
this.doGet(request, response);
}
}
四、小结:
Cookie和Session都是来完成一次会话内多次请求间数据共享的,它们之间的区别有如下五种:
- 存储位置:Cookie将数据存储在客户端,Session则是存储在了服务器端
- 数据大小:Cookie最大3kb,Session的大小无限制
- 安全性:Cookie不安全,Session安全
- 存储时间:Cookie可以长期存储,Session默认为三十分钟
- 服务器性能:Cookie不占服务器资源,二Session占服务器资源
具体使用Session还是Cookie需要根据场景需要具体而定~~~~
-END;