什么是 session
我们知道 HTTP 是无状态协议,这意味着每次客户端检索网页时,都要单独打开一个服务器连接,因此服务器不会记录下先前客户端请求的任何信息。而
本来有下面几种方式来保持客户端和服务器会话。
- Cookies
网络服务器可以指定一个唯一的 session ID 作为 cookie 来代表每个客户端,用来识别这个客户端接下来的请求。但是很多时候浏览器并不一定支持 cookie,所以不建议使用这种方法来维持会话。
- 隐藏表单域
网络服务器可以发送一个隐藏的HTML表单域和一个唯一的session ID。
范例:
<input type="hidden" name="sessionid" value="12345">
当表单被提交时,指定的名称和值将会自动包含在GET或POST数据中。每当浏览器发送一个请求,session_id的值就可以用来保存不同浏览器的轨迹。但是 a 标签的超连接跳转是不会发生表单提交,所以就不会发生会话跟踪了。
- 重写 URL
以在每个URL后面添加一些额外的数据来区分会话,服务器能够根据这些数据来关联session标识符。
网址与编码信息通过"?"号分隔。如下所示:
http://www.xxx.com/hello.html?key1=value1&key2=value2&session=12345
缺点是您必须为每个URL动态指定session ID,而且信息暴露。
以上的几种方式,看起来都不大聪明的样子,这时候需要我们的 session 对象了。
具体内容
JSP 利用 servlet 提供的 HttpSession 接口来识别一个用户,存储这个用户的所有访问信息(类似通过 setAttribute() 方法,可以把信息保存到,直到浏览器关闭。)。默认情况下,JSP 允许会话跟踪,一个新的 HttpSession 对象将会自动地为新的客户端实例化。禁止会话跟踪需要显式地关掉它,通过将 pag e指令中 session 属性值设为false来实现。
应用
session 除了设置和获取域对象之外,还有下面几个功能。
-
判断浏览器是否是第一次访问
-
获取sessionID
-
用户的注销
对于这几个功能,主要利用下面几个方法:
- 获取 sessionID
public String getId()
- 判断浏览器是否是第一次访问服务器,如果是则返回 true,否则返回 false
public boolean isNew()
- 使 session 存储的值失效
public void invalidate()
还有其他方法,例如
-
移除一个特定的属性:
public void removeAttribute(String name)
方法来移除指定的属性。
-
设置会话有效期:
public void setMaxInactiveInterval(int interval)
方法来设置session超时。- Tomcat中的默认的超时时间是30分钟。
-
登出用户:
支持servlet2.4版本的服务器,可以调用
logout()
方法来登出用户,并且使所有相关的session无效。
判断是否为新用户
示例代码
<%
if(session.isNew()){
%>
<h1>您是新人</h1>
<%
}else{
%>
<h1>您是老人</h1>
<%
}
%>
判断是否是新的用户在开发中使用的比较少,一般来说的话,用的网站会使用访问计数器,进行页面访问的时候回判断是否是新的用户,如果是新的用户,计数器回加1,否则计数器不会增加。
注销功能
session 失效,就是一个注销的功能,在实际中,很多系统需要用户进行登录之后才能够访问,比如学校的教务系统,登录成功之后将用户的信息保存在 session 域对象中,用户注销之后,session域对象中的信息就不存在了,再跳转到登录页面,这个时候注销的功能就完成了。
在注销按钮对应的页面可以这样写:
<%
session.invalidate();//使session失效
response.sendRedirect("login.jsp");
%>
session ID
在每当一个浏览器第一次访问服务器的时候,服务器会默认设置一个 JSSESSIONID 到浏览器的 Cookie 中。服务器也靠着 Cookie 中的 JSESSIONID 区分不同的浏览器。
实例
<%
Cookie cooks[] = request.getCookies();
if(null != cooks && cooks.length >= 1){//第一次访问的时候,浏览器的Cookie中还不存在JSESSIONID,所以先判断
for(Cookie cook:cooks){
%>
<h1><%= cook.getName() + "--->" + cook.getValue() %></h1>
<%
}
}
%>
注意的是,第一访问的是不存在的,服务器在第一次访问才设置进去,如果第一次直接访问可能报出空指针异常。
而 session 获取的 ID 和 Cookie 中的 JSESSIONID 是一样的。实际上session.getID()
也是在 Cookie 中获取
什么是 application
application 对象是 ServletContext 这个接口的对象。ServletContext 表示的是 Servlet 的上下文。那么 ServletContext 代表整个web应用,可以和程序的容器(服务器)来通信。
那么如何获得该对象?从对象的从属关系上看。我们知道 jsp 其实也是 servlet,而 servlet 的继承关系如下:
- Servlet 接口
- GenericServlet 抽象类
- HttpServlet 抽象类
- GenericServlet 抽象类
通过查看 GenericServlet 源码,我们发现如下源码:
@Override
public ServletContext getServletContext() {
return getServletConfig().getServletContext();
}
那么,对于 jsp 来说,既然父类拥有获取的方法,那么我们可以通过
this.getServletContext()
来获取。
同时也建议用以上的方式获取,虽然 servletcontext 主要用在 servlet 中,当然也可以在jsp中使用,而 application 只在jsp页面中使用。两个用法是一样的。
作用
域对象操作,已经获取虚拟目录的真实路径。
什么是虚拟目录的真实路径?在浏览器中访问一个 jsp ,这个 jsp 访问路径实际是 tomcat 的运行路径,那么实际路径,实际得靠 application 对象的String getRealPath(String path)
才能获取。
范例:获得虚拟目录的真实路径
<h1>这是一个Application</h1>
<!-- 取得一个jsp的真实地址 -->
<h3><%=application.getRealPath("/application/application01.jsp") %></h3>