Java学习笔记-Day55 会话跟踪
一、会话跟踪概述
对于Web应用来说,会话(Session)就是浏览器与服务器之间的一次连续的通讯过程。
HTTP协议是无状态的,也就是说,一次请求结束后,HTTP协议就不再记录相关信息。
会话跟踪技术能够跟踪客户端与服务器端的交互,保存和记忆相关的信息,保存请求的状态信息。会话跟踪能够保存状态信息,解决HTTP协议无状态特性的弊端
二、常用的会话跟踪技术
常用的会话跟踪技术有四种:
(1)URL方式:需要保存的信息直接追加到URL后,例如:http://127.0.0.1:8080/BlogSytem/Servlet.do?username=tom&pwd=123456
(2)隐藏域方式:可以使用表单中的隐藏域保存相关信息, 例如:
<input type="hidden" name=“status" value=“true">
(3)Cookie方式:将状态信息保存到客户端,服务器能够获得相关信息进行分析,从而生成对客户端的响应;例如简化登录功能就可以使用Cookie实现。
(4)Session方式:将状态信息保存到服务器的会话对象中,通过唯一标记的ID值与客户端进行绑定使用;例如访问控制功能就可以使用Session实现。
例如存储用户登录的数据:① Session(保存在服务端) ② Cookie(保存在客户端)
三、Cookie和Session
1、Cookie
Cookie是一段保存在客户端的小文本;能够用来将用户活动过程中的状态信息保存到客户端,服务器可以获得该信息以便进行处理,跟踪到用户的状态。
不同的浏览器有不同的查看方式。以Chrome浏览器为例,查看当前页面cookie 的方法:设置——>隐私和设置的安全性——>Cookie以及其它网站数据——>查看所有的Cookie和网站数据,就可以看到所有的cookie信息。也可以通过F12——>Application——>cookies,查看当前网站的cookie。
Cookie包含一系列的属性:
- name:cookie的名字,每个cookie都有一个名字。
- content:cookie的值,与名字一起作为键值对形式存在。
- domain:域,该cookie的域名,例如左图中是163.com,说明当前cookie来自163.com。
- path:路径,访问163.com下该路径时,当前cookie将被发送。
- created:cookie被创建的时间。
- Expired:cookie失效的时间。
- 最大生命时间:失效时间和创建时间的时间差,就是cookie的最大生命时间,超过该时间,cookie将失效,不再被发送到相应的域地址。
Servlet规范中定了Cookie类 ( javax.servlet.http.Cookie ),创建该类对象就可以创建Cookie,并可以调用其中方法为Cookie设置属性。
方法声明 | 方法描述 |
---|---|
Cookie(java.lang.String name, java.lang.String value) | 创建Cookie对象,指定名字和对应的值; |
void setMaxAge(int expiry) | 设置最大生命时间(秒),如果不设置,当前浏览器关闭,cookie即失效; |
void setValue(java.lang.String newValue) | 设置Cookie的值; |
setDomain(java.lang.String domain) | 设置cookie的域名; |
要将Cookie保存到客户端,就要将其添加到响应对象才可以。响应接口中定义了设置Cookie的方法:
方法声明 | 方法描述 |
---|---|
void addCookie(Cookie cookie) | 将Cookie对象保存到相应的响应对象中; |
Cookie cookie1 = new Cookie("username", user.getUname());
Cookie cookie2 = new Cookie("pwd", user.getUpwd());
cookie1.setMaxAge(60 * 60 * 24);
cookie2.setMaxAge(60 * 60 * 24);
response.addCookie(cookie1);
response.addCookie(cookie2);
当访问相同域及路径时,没有超过有效时间的cookie将自动通过请求被发送到网站。Servlet规范中的请求接口定义了获取Cookie对象的方法:
方法声明 | 方法描述 |
---|---|
Cookie[] getCookies() | 获取请求中的所有Cookie对象,返回数组; |
<%
String username = "";
String userpwd = "";
Cookie[] cookies = request.getCookies();
for (Cookie ck : cookies) {
if (ck.getName().equals("username")) {
username = ck.getValue();
}
if (ck.getName().equals("pwd")) {
userpwd = ck.getValue();
}
}
%>
2、Session
Session是存储在服务器上的对象,该对象由服务器创建并维护。服务器为客户端与服务器的每一次会话过程都创建并维护一个Session对象。每个服务器对Session的创建和维护的底层实现有所区别。
Tomcat使用Cookie来维护Session对象的ID值,该Cookie名字为JSESSIONID。
每个Session对象都有一个唯一的ID值,这个ID值存储在名字为JSESSIONID的Cookie中。
当客户端开始一次会话过程时,以Tomcat为例,步骤如图:
Servlet规范中定义了HttpSession接口,用来实现Session技术。要使用HttpSession,首先要获取其对象。请求接口中定义了获取HttpSession对象的方法:
方法声明 | 方法描述 |
---|---|
HttpSession getSession() | 获取与当前请求相关的Session对象,如果不存在,创建一个新的; |
HttpSession getSession(boolean create) | 如果create为true,则与getSession()方法相同;如果create是false,则如果不存在,返回null; |
HttpSession session = request.getSession();
有了会话属性,就可以在会话范围内共享对象。与前面学习过的请求属性类似,会话也可以添加、修改、删除属性。HttpSession接口中提供了与属性有关的方法:
方法声明 | 方法描述 |
---|---|
void setAttribute(java.lang.String name, java.lang.Object o) | 将任意类型对象设置为会话的属性,指定一个名字; |
java.lang.Object getAttribute(java.lang.String name) | 通过属性的名字,获取属性的值; |
void removeAttribute(java.lang.String name) | 通过属性的名字,删除属性; |
HttpSession session = request.getSession();
session.setAttribute("user", user);
让Session失效原因:会话对象是存储在服务器端的对象,一直存在需要占用一定的服务器资源。会话中往往保存着用户的一些数据,如果一直有效,存在一定安全隐患。
Session失效的方法:服务器都有默认的会话失效时间,Tomcat默认是30分钟;
可以在web.xml中配置失效时间,以分钟为单位。
<session-config>
<session-timeout>50</session-timeout>
</session-config>
调用HttpSession接口中的两个方法,可以对指定的会话对象进行销毁。
方法声明 | 方法描述 |
---|---|
void setMaxInactiveInterval(int interval) | 为特定的会话对象设定不活动时间,超过这个时间内没有被访问使用,容器自动销毁该会话对象; |
void invalidate() | 立刻销毁调用该方法的会话对象,并把所有绑定到该会话的对象解除绑定; |
四、使用Ajax获取数据
后端传递前端的数据是Json格式,主要工具有gson(java类库)、fastjson(阿里的)、jackson(框架使用,多个jar包)。
实现步骤:
1、后端
① 将gson.jar放到WebContent下的WEB-INF下的lib目录中。
② 设置响应格式。response.setContentType("application/json;charset=utf-8");
③ Gson gson = new Gson(); String str = gson.toJson(list);
④ PrintWriter out = response.getWriter(); out.print(str);
2、前端
① <script src="js/jquery-2.0.3.js" type="text/javascript" charset="utf-8"></script>
② $.get("url地址", function(res) { 代码 });
③ 遍历并处理结果。
注意:${v.userid}
在html页面中默认为ECMAscript6中的模板字符串,而在JSP页面中默认为EL表达式。在JSP页面中,EL表达式也是使用 $ 符号来插入变量的,所以在模板字符串中使用 $ 符号会造成冲突从而不会被识别。在Ajax中使用的是模板字符串,${v.userid}
会被JSP解析成空字符串,所以必须在JSP中将模板字符串的${}
进行转义,前面加个斜杠写成\${}
,跟EL表达式区分开来。
- AjaxServlet.java
import java.io.IOException;
import java.io.PrintWriter;
import java.util.List;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import com.etc.bs.entity.User;
import com.etc.bs.service.UserService;
import com.google.gson.Gson;
/**
* Servlet implementation class AjaxServlet
*/
@WebServlet("/AjaxServlet.do")
public class AjaxServlet extends HttpServlet {
private static final long serialVersionUID = 1L;
private UserService userservice = new UserService();
/**
* @see HttpServlet#HttpServlet()
*/
public AjaxServlet() {
super();
}
/**
* @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse
* response)
*/
protected void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
request.setCharacterEncoding("utf-8");
String op = "";
if (request.getParameter("op") != null) {
op = request.getParameter("op");
}
if ("login".equals(op)) {
doLogin(request, response);
} else {
doQuery(request, response);
}
}
/**
* @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse
* response)
*/
protected void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
doGet(request, response);
}
/**
* @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse
* response)
*/
protected void doQuery(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
// 设置响应格式
response.setContentType("application/json;charset=utf-8");
String keywords = "";
if (request.getParameter("keywords") != null) {
keywords = request.getParameter("keywords");
}
// keyword赋值为""
List<User> list = userservice.getUserByName(keywords);
// 创建Gson对象
Gson gson = new Gson();
// 将list转换成json格式的字符串
String str = gson.toJson(list);
PrintWriter out = response.getWriter();
out.print(str);
}
/**
* @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse
* response)
*/
protected void doLogin(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
}
}
- ajax.html
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Insert title here</title>
<style type="text/css">
td {
border: 1px solid black;
}
#tab {
width: 600px;
text-align: center;
}
</style>
</head>
<body>
<button type="button" id="btn">获取数据</button>
<div id="div1">
<table id="tab" border="1" cellspacing="0" cellpadding="20">
<tr>
<th>编号</th>
<th>名字</th>
<th>密码</th>
<th>年龄</th>
<th>性别</th>
<th>操作</th>
</tr>
</table>
</div>
<script src="js/jquery-2.0.3.js" type="text/javascript" charset="utf-8"></script>
<script type="text/javascript">
$(function() {
//按钮的单击事件
$("#btn").click(function() {
//$(selector).get(url,data,success(response,status,xhr),dataType)
//参数 url地址,参数回调函数
$("#tab").html(`<tr>
<th>编号</th>
<th>名字</th>
<th>密码</th>
<th>年龄</th>
<th>性别</th>
<th>操作</th>
</tr>
`);
$.get("http://127.0.0.1:8080/BlogSystem/AjaxServlet.do", function(res) {
$.each(res, function(index, v) {
//遍历一次就加一行数据
$("#tab").append(`<tr>
<td>${v.userid}</td>
<td>${v.uname}</td>
<td>${v.upwd}</td>
<td>${v.uage}</td>
<td>${v.usex}</td>
<td><input type="button" class="btndel" value="删除"></td>
</tr><br/>`
);
});
});
});
});
</script>
<script type="text/javascript">
$(function () {
$(document).on("click",".btndel",function () {
console.log($(this).parents("tr").children("td:eq(0)").text())
$(this).parents("tr").remove();
});
});
</script>
</body>
</html>