Java Web 学习与总结(三)会话跟踪
何为会话跟踪?举个简单的例子,比如登陆到某购物网站后,在一定时间内无论你在这个网站中切换到任意的网页,只要不执行退出操作,一直保持着你账号的登录状态。
那么在Java Web中我们应当如何去实现这一操作呢?这里给大家介绍三种技术:cookie、session和URL重写技术。
首先是cookie技术,cookie在平时我们的使用时经常可以在安全设置中看到,它其实是服务器段在客户端本地保存的一些数据,同之前我们学到的Arribute一样,也是由key-value结构组成的。它是一种在客户端保持绘画跟踪的解决方案。在用户第一次访问服务器时,由服务器通过响应头的方式发送给客户端浏览器;当用户再次向服务器发送请求时会附带上这些文本信息。通过cookie,服务器在手收到来自客户端浏览器的请求时,能够通过分析请求头的内容而得到客户端特有的信息,从而动态的生成与该客户端相对应的内容,比如在很多网站登录时我们会看到类似“记住我”的选项,其实选中了就是把你的登陆信息保存在本地了,下次访问网站时自然而然的就附带了上次的登陆信息,从而达到免再次登陆的功能。
cookie在javax.servlet.http内的源码:
//
// Source code recreated from a .class file by IntelliJ IDEA
// (powered by Fernflower decompiler)
// package javax.servlet.http; import java.io.Serializable;
import java.security.AccessController;
import java.security.PrivilegedAction;
import java.util.Locale; public class Cookie implements Cloneable, Serializable {
private static final CookieNameValidator validation;
private static final long serialVersionUID = 1L;
private final String name;
private String value;
private int version = ;
private String comment;
private String domain;
private int maxAge = -;
private String path;
private boolean secure;
private boolean httpOnly; public Cookie(String name, String value) {
validation.validate(name);
this.name = name;
this.value = value;
} public void setComment(String purpose) {
this.comment = purpose;
} public String getComment() {
return this.comment;
} public void setDomain(String pattern) {
this.domain = pattern.toLowerCase(Locale.ENGLISH);
} public String getDomain() {
return this.domain;
} public void setMaxAge(int expiry) {
this.maxAge = expiry;
} public int getMaxAge() {
return this.maxAge;
} public void setPath(String uri) {
this.path = uri;
} public String getPath() {
return this.path;
} public void setSecure(boolean flag) {
this.secure = flag;
} public boolean getSecure() {
return this.secure;
} public String getName() {
return this.name;
} public void setValue(String newValue) {
this.value = newValue;
} public String getValue() {
return this.value;
} public int getVersion() {
return this.version;
} public void setVersion(int v) {
this.version = v;
} public Object clone() {
try {
return super.clone();
} catch (CloneNotSupportedException var2) {
throw new RuntimeException(var2);
}
} public void setHttpOnly(boolean httpOnly) {
this.httpOnly = httpOnly;
} public boolean isHttpOnly() {
return this.httpOnly;
} static {
boolean strictServletCompliance;
String propStrictNaming;
String propFwdSlashIsSeparator;
if (System.getSecurityManager() == null) {
strictServletCompliance = Boolean.getBoolean("org.apache.catalina.STRICT_SERVLET_COMPLIANCE");
propStrictNaming = System.getProperty("org.apache.tomcat.util.http.ServerCookie.STRICT_NAMING");
propFwdSlashIsSeparator = System.getProperty("org.apache.tomcat.util.http.ServerCookie.FWD_SLASH_IS_SEPARATOR");
} else {
strictServletCompliance = (Boolean)AccessController.doPrivileged(new PrivilegedAction<Boolean>() {
public Boolean run() {
return Boolean.valueOf(System.getProperty("org.apache.catalina.STRICT_SERVLET_COMPLIANCE"));
}
});
propStrictNaming = (String)AccessController.doPrivileged(new PrivilegedAction<String>() {
public String run() {
return System.getProperty("org.apache.tomcat.util.http.ServerCookie.STRICT_NAMING");
}
});
propFwdSlashIsSeparator = (String)AccessController.doPrivileged(new PrivilegedAction<String>() {
public String run() {
return System.getProperty("org.apache.tomcat.util.http.ServerCookie.FWD_SLASH_IS_SEPARATOR");
}
});
} boolean strictNaming;
if (propStrictNaming == null) {
strictNaming = strictServletCompliance;
} else {
strictNaming = Boolean.parseBoolean(propStrictNaming);
} boolean allowSlash;
if (propFwdSlashIsSeparator == null) {
allowSlash = !strictServletCompliance;
} else {
allowSlash = !Boolean.parseBoolean(propFwdSlashIsSeparator);
} if (strictNaming) {
validation = new RFC2109Validator(allowSlash);
} else {
validation = new RFC6265Validator();
} }
}
从源码中我们可以看到cookie对象的构造函数是public Cookie(String name, String value),那么我们在Servlet中创建cookie也是根据这种构造方法来创建(这里命名为unameCookie):
Cookie unameCookie = new Cookie("key","value");
创建对象后,我们服务器向客户端响应Cookie时需要这一函数:
response.addCookie(unameCookie);
通过这两步后,我们便将名字为key,值为value的Cookie对象保存在了用户的客户机上,当我们要使用cookie内保存的数据时时需要通过以下方法获取并遍历:
Cookie[] cookies = request.getCookie();
String value = null;
if(cookies != null){
for(Cookie c: cookies){
if(c.getName() .equal("key")){
value = c.getValue();
}
}
}
这里通过request.getCookie()得到响应头中的cookie内容,然后通过遍历cookie数组比较通过getName()得到的名字,再获取我们需要的值。
但是我们要注意,在默认情况下cookie只能被创建它的应用获取。Cookie的setPath()方法可以重新指定其访问路径,例如将其设置为在某个应用下的某个路径共享,或者在同一服务器内的所有应用共享:
unameCookie.setPath("/chapter/jsp/");
这样就让unameCookie能在/chapter/jsp/目录下所有的应用共享,当然我们也可以通过以下方式让服务器下的所有应用共享:
unameCookie.setPath("/");
Cookie有一定的存活时间,不会在客户端一直保存。默认情况下,Cookie保存在浏览器内存中,在浏览器关闭时失效,这种Cookie也成为临时Cookie,若要其长时间保存,我们需要通过setMaxAge()方法设置其存活时间(以秒为单位),时间若为正整数,表示其存活的秒数,若为负数,表示为临时Cookie,若为0,则通知浏览器删除相应的Cookie。
unameCookie.setMaxAge(60*60);//保存一个小时的cookie
要注意,保存的Cookie仅限在同一个浏览器下且允许Cookie下访问来使用,cookie可能被禁用,可能被其他软件删除,它的大小和个数受限,单个不能超过4kb,很多浏览器都只允许一个站点最多保持20个Cookie,另外,它的安全性也不够高,是以纯文本的形势记录在文件中,最好在保存前加密处理一下。
再一个就是最常用的Session技术,这是一种在服务器端保持会话跟踪的解决方案,使用了HttpSession对象,这个对象是javax.servlet.http.HttpSession接口的实例,也称为会话对象,该对象用来保存单个用户访问时的一些信息,是服务器在无状态的HTTP协议下用来识别和维护具体某个用户的主要方式。
HttpSession对象会在用户第一次访问服务器时由容器创建(注意只是在访问JSP、Servlet等程序在会创建,访问静态资源并不会创建),当用户调用其失效方法(invalidate()方法)或超过其最大不活动时间时会失效。在此期间,来自同一客户端的用户与服务器之间的多次请求都属于同一会话。
服务器在创建会话对象时,会为其分配一个唯一的会话标识:SessionId,以JSESSIONID的属性名保存在客户端Cookie中,在用户随后的请求中,服务器通过该Cookie中的JSESSIONID属性值来识别不同的用户。
从这里我们看出,实际上通过读取存取临时Cookie我们就可以达到保持用户连接的功能,Session技术实际就是把这一功能规范化,但是数据是存储在服务器上,当访问量增多时会造成服务器性能负担加重,下面我们来看如何使用这一技术。
HttpSession源码:
//
// Source code recreated from a .class file by IntelliJ IDEA
// (powered by Fernflower decompiler)
// package javax.servlet.http; import java.util.Enumeration;
import javax.servlet.ServletContext; public interface HttpSession {
long getCreationTime(); String getId(); long getLastAccessedTime(); ServletContext getServletContext(); void setMaxInactiveInterval(int var1); int getMaxInactiveInterval(); /** @deprecated */
@Deprecated
HttpSessionContext getSessionContext(); Object getAttribute(String var1); /** @deprecated */
@Deprecated
Object getValue(String var1); Enumeration<String> getAttributeNames(); /** @deprecated */
@Deprecated
String[] getValueNames(); void setAttribute(String var1, Object var2); /** @deprecated */
@Deprecated
void putValue(String var1, Object var2); void removeAttribute(String var1); /** @deprecated */
@Deprecated
void removeValue(String var1); void invalidate(); boolean isNew();
}
Session的使用方法如下:
获取HttpSession对象:HttpSession session = request.getSession();
存取会话值属性:
存储:session.setAttribute("key","name");
取出:String uanme = (String)session.getAttribute("key");
移除:session.removeAttribute("key");
这里实际上和存取Cookie差不多,这一会话在网站服务器路径下的应用中都保持一致,存储的value对象也不仅仅是String,是任意的对象(泛型),需要什么就存什么,只需要在取出是转化为当时存储的类型就好了,
获取会话的最大不活动时间:
int time = session.getMaxInactiveInterval();//单位为秒
设置会话的最大不活动时间:
session.setMaxInactiveInterval(600);
设置会话立刻失效:
session.invalidate();
服务器在执行会话失效代码后,会立刻清除会话对象及其所有会话域属性,同时响应客户端浏览器清除Cookie中的JSESSIONID。在实际应用中此方法多用来实现系统的“安全退出”,使客户端和服务器彻底结束此次回话,清除所有会话相关信息,防止会话劫持等黑客攻击,
此外,在多数情况下,Session需要借助Cookie才能正常工作,如果客户端完全禁止Cookie,Session将失效。
URL重写技术主要是在不能确定客户端浏览器是否支持Cookie的情况下,使用URL重写技术可以对请求的URL地址追加会话标识,从而实现用户的会话跟踪功能。URL重写是指服务器程序对接收的URL请求重新写成网站可以处理的另一个URL过程,URL重写技术是实现动态网站会话跟踪的的重要保障。
例如对于一个请求地址:http://localhost:8080/chapter/Servlet1
经过重写后,地址格式变为:http://localhost:8080/chapter/Servlet1;jsessionid=5678978e7r9w7r8we7r8w7e89r7we9
其中的jsessionid是不是在上一段中是不是很熟悉!!!这就是通过url追加的会话标识,服务器即通过它来识别跟踪某个用户的访问。
URL重写的示例代码如下所示:
1.encodeURL方法:out.Print("<a href=' " + response.encodeURL("Servlet1" + " ')'>链接请求</a>")
2.encodeRedirectURL方法:response.sendRedirect(response.encodeRedirectURL("Servlet1"));
在使用时,我们通常用一个String对象来获取encodeURL方法得到的链接来进行请求,用encodeRedirectURL方法来进行重定向来进行Session的保持。
还用一种是通过form表单隐藏域来进行,但这种方法只能通过表单来传递标志信息,意义不大,这里不再叙述。
Java Web 学习与总结(三)会话跟踪的更多相关文章
- [原创]java WEB学习笔记31:会话与状态管理 session机制 概述(定义,session机制,session的声明周期,保存session的方式,Session的创建与删除)
本博客为原创:综合 尚硅谷(http://www.atguigu.com)的系统教程(深表感谢)和 网络上的现有资源(博客,文档,图书等),资源的出处我会标明 本博客的目的:①总结自己的学习过程,相当 ...
- [原创]java WEB学习笔记28: 会话与状态管理Cookie 机制
本博客为原创:综合 尚硅谷(http://www.atguigu.com)的系统教程(深表感谢)和 网络上的现有资源(博客,文档,图书等),资源的出处我会标明 本博客的目的:①总结自己的学习过程,相当 ...
- Java Web学习笔记之---JSP
Java Web学习笔记之---JSP (一)JSP常用语法 (1)HTML注释 <!--所要注释的内容 --> 在客户端显示一个注释. (2)隐藏注释 <%--所要注释的内容--% ...
- JAVA Web学习笔记
JAVA Web学习笔记 1.JSP (java服务器页面) 锁定 本词条由“科普中国”百科科学词条编写与应用工作项目 审核 . JSP全名为Java Server Pages,中文名叫java服务器 ...
- Java Web 学习路线
实际上,如果时间安排合理的话,大概需要六个月左右,有些基础好,自学能力强的朋友,甚至在四个月左右就开始找工作了.大三的时候,我萌生了放弃本专业的念头,断断续续学 Java Web 累计一年半左右,总算 ...
- Java Web学习系列——Maven Web项目中集成使用Spring、MyBatis实现对MySQL的数据访问
本篇内容还是建立在上一篇Java Web学习系列——Maven Web项目中集成使用Spring基础之上,对之前的Maven Web项目进行升级改造,实现对MySQL的数据访问. 添加依赖Jar包 这 ...
- Java Web学习系列——Maven Web项目中集成使用Spring
参考Java Web学习系列——创建基于Maven的Web项目一文,创建一个名为LockMIS的Maven Web项目. 添加依赖Jar包 推荐在http://mvnrepository.com/.h ...
- Java web 学习之旅
java web学习之旅 来公司十天了,感觉已经慢慢地融入了这个环境中,几个学长人都很好,都是在他们帮助下,我才能比较顺利的开始了学习java web的旅途. 来这里学习的第一个阶段是做一个简单的用户 ...
- [原创]java WEB学习笔记95:Hibernate 目录
本博客的目的:①总结自己的学习过程,相当于学习笔记 ②将自己的经验分享给大家,相互学习,互相交流,不可商用 内容难免出现问题,欢迎指正,交流,探讨,可以留言,也可以通过以下方式联系. 本人互联网技术爱 ...
- [原创]java WEB学习笔记75:Struts2 学习之路-- 总结 和 目录
本博客的目的:①总结自己的学习过程,相当于学习笔记 ②将自己的经验分享给大家,相互学习,互相交流,不可商用 内容难免出现问题,欢迎指正,交流,探讨,可以留言,也可以通过以下方式联系. 本人互联网技术爱 ...
随机推荐
- eclipse中项目出现红色的!
eclipse中项目出现红色的!的原因有二个:1.jdk不匹配 2.缺少jar包
- 使用heroku创建应用时报错 heroku does not appear to be a git repository
在跟着heroku的官方教程创建python应用时,到deploy-the-app这一步,要上传代码到heroku 的git仓库时,报的这个错误: 网上一搜,相关的答案居然极少,首页只出现一篇(还好这 ...
- 可用于nodejs的SuperAgent(ajax API)
简单示例: import request from 'superagent';//引用声明 request.post(api) .withCredentials()//跨域 .end((err, re ...
- centos7 ntp服务器配置
一.ntp服务是什么 1. 定义 NTP是网络时间协议(Network Time Protocol),它是用来同步网络中各个计算机的时间的协议. 2. 发展 首次记载在Internet Enginee ...
- Cplus Overolad new and delete Operator
思考:在C++类中,通过设计类的构造和析构函数,就已经把复杂的内存管理起来了. 及时是简单的结构体,也是有构造和析构函数的,而下面这种情况,可以在非结构中使用. /** Operator Overlo ...
- 我的border能自定义四角之border-radius : 左上角,右上角,左下角,右下角。
1 边框:border: 1px solid #0081df; 2 想要单独加上四个圆角: border-bottom-left-radius: 5px; border-top-left-radius ...
- UVa 10603 Fill (暴力BFS+优先队列)
题意:给定4个数,a,b,c,d,分别代表空杯子容积为a,b,一个盛满水的杯子容积为c,让你不断倒水,找一个dd,是不是存在某个时刻, 某个杯子里的水dd,和d相同,或者无限接近.让求最少的倒水量和d ...
- 日志文件(关于#IRSA_MDPS_RDM软件 密码登录事项 7月26号)
1.登录:sqlplus 用户名:scott 口令:123 qweas.. //2018-7-16号更改密码 2.查看该用户(已登录)下有几个表:select table_name from user ...
- swift -pop的简单动画
//1.新建空文件 命名Podfile //2.写入 pod ‘pop’,’~>1.0’ 保存 //3.打开终端,进入项目路径 执行pod install //4.新建桥接头文件 导入#im ...
- 23 DesignPatterns学习笔记:C++语言实现 --- 2.4 Composite
23 DesignPatterns学习笔记:C++语言实现 --- 2.4 Composite 2016-07-22 (www.cnblogs.com/icmzn) 模式理解