`
ericwzc
  • 浏览: 12706 次
  • 性别: Icon_minigender_1
  • 来自: 南京
社区版块
存档分类
最新评论

HttpSession 是什么时候产生的?

    博客分类:
  • web
 
阅读更多

本文用实验来证明session在servlet和jsp技术是如何应用的。大家都知道session由容器产生和管理,那么是什么时候产生的呢?不用多说了,用代码来证明一切吧。

 

首先,我们创建一个sessionlistener 来跟踪每个session的轨迹。

 

public class MySessionListener implements HttpSessionListener {

	@Override
	public void sessionCreated(HttpSessionEvent arg0) {
		String id = arg0.getSession().getId();
		System.out.println("session with id " + id +" created");
	}

	@Override
	public void sessionDestroyed(HttpSessionEvent arg0) {
		String id = arg0.getSession().getId();
		System.out.println("session with id " + id + "destroyed");
	}

}

 

修改web.xml使listerner生效

        <listener>
        	<listener-class>
        		org.eric.listeners.MySessionListener
        	</listener-class>
        </listener>

创建一个greet.jsp

<%@ page language="java" contentType="text/html; charset=ISO-8859-1"
	pageEncoding="ISO-8859-1" session="false"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
<title>Test Session</title>
</head>
<body>
	<a href="<%= response.encodeURL("/scwcd/greet.jsp") %>">request the same page again</a>
</body>
</html>

 

请注意,我的工程名叫scwcd, 为了看到效果,我们故意把jsp中session设为false, 因为默认是true的,也就是使用session.

现在我们清除浏览器的cookie,然后我们在firefox中打开firebug,选中net选项卡,然后发请求http://localhost/scwcd/greet.jsp

结果server端没有session with id... created 的输出,firebug 中response header中便找不到set-cookie, 如下

HTTP/1.1 200 OK
Server: Apache-Coyote/1.1
Content-Type: text/html;charset=ISO-8859-1
Content-Length: 354
Date: Sat, 06 Apr 2013 06:52:31 GMT

 

这意味着server并没有开始我们的会话,换句话说server并不care我们究竟是谁,不管我们发多少次请求。

 

现在我们声明在server端使用session, 去掉session=“false”, 或者改session="true", 并且在浏览器端允许使用cookie. 再次发送请求,http://localhost/scwcd/greet.jsp, session真的出来了,

server端输出了,session with id 814E7FAFCEC4724831E1B3E5CAEF0096 created, 浏览器端查看reponse header, 如下

HTTP/1.1 200 OK
Server: Apache-Coyote/1.1
Set-Cookie: JSESSIONID=814E7FAFCEC4724831E1B3E5CAEF0096; Path=/scwcd/; HttpOnly
Content-Type: text/html;charset=ISO-8859-1
Content-Length: 398
Date: Sat, 06 Apr 2013 06:57:06 GMT

 

我们的后面的请求都会带上cookie了,这样服务器就知道我们是谁了,不信?可以再发一次请求http://localhost/scwcd/greet.jsp,这次看request header, 发现红色的多出来了

 

GET /scwcd/greet.jsp HTTP/1.1
Host: localhost:8888
User-Agent: Mozilla/5.0 (Windows NT 6.1; rv:20.0) Gecko/20100101 Firefox/20.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: en-US,en;q=0.5
Accept-Encoding: gzip, deflate
Cookie: JSESSIONID=814E7FAFCEC4724831E1B3E5CAEF0096
Connection: keep-alive

 

Cookie 就是这样工作的,服务器端set-cookie之后,后面的每次请求都会加上cookie. 这样服务器端就知道他在跟谁对话了,这样就使得本来无状态的http协议变得似乎有状态了,cookie中的信息可以实现客户端与服务器端共享。然而,cookie不能滥用,其大小是有限制的,不能在里面放太多东西,当然仅仅放放我们的身份识别符sessionid还是绰绰有余了。

 

问题一, 如果上文中用的是servlet,而不是jsp会怎么样?

jsp归根到底是servlet,还是用实验来证明吧,创建servlet如下

 

public class MyServlet extends HttpServlet {

	public void init() {
		System.out.println("MyServlet initialized");
	}

	public void doGet(HttpServletRequest request, HttpServletResponse response)
			throws IOException {
		request.getSession();
         }
}

 

修改web.xml, 加入下面的内容

       <servlet>
            <servlet-name>MyServlet</servlet-name>
            <servlet-class>org.eric.MyServlet</servlet-class>
       </servlet>
        <servlet-mapping>
            <servlet-name>MyServlet</servlet-name>
            <url-pattern>/MyServlet</url-pattern>
        </servlet-mapping>

 

重新清除浏览器cookie, 发请求http://localhost/scwcd/MyServlet, 结果服务器端和客户端都显示session是被创建出来了。不难想到,服务器端得到我们的http请求, 其中自然可以获取jsessionid(不管是从querystring 获取还是cookie), 然后把根据这个id从容器维护的 session中找到对应的session对象。而getSession()这个方法如果找不到那个session对象,就会创建一个,并且告诉客户端对应的ID, 即jsessionid(请看问题二如有疑问). 对于我们清掉cookie后第一次请求,header中不包含cookie(jsessionid),浏览器无从知道我们还是老客户:),  所以就新建一个session来跟我们会话。

 

改改试试,上面的servlet 中改为request.getSession(false), 清掉浏览器cookie再发请求http://localhost/scwcd/MyServlet; 结果显示没有创建session. 因为getSession(false)方法如果找不到session对象,就返回null, 并不会新建session对象。

 

问题二, 听说如果浏览器禁用cookie,server端会修改url加上jsessionid, 来实现会话,那究竟是cookie呢还是先修改url呢, 即server端是如何知道浏览器端有没有禁用cookie的?

我们清掉浏览器端的cookie, 并且在浏览器禁用cookie, Firebug---Cookies---Deny cookies from localhost.

在greet.jsp改session=“true".  发请求http://localhost/scwcd/greet.jsp

response header, 结果 跟刚才一样, 包含set-cookie

HTTP/1.1 200 OK
Server: Apache-Coyote/1.1
Set-Cookie: JSESSIONID=1EFB388FE94172438DCC2B02378EE1DA; Path=/scwcd/; HttpOnly
Content-Type: text/html;charset=ISO-8859-1
Content-Length: 398
Date: Sat, 06 Apr 2013 08:38:33 GMT

 

留心一下,返回的html页面,发现这行了吗?

<a href="/scwcd/greet.jsp;jsessionid=1EFB388FE94172438DCC2B02378EE1DA">request the same page again</a>

 

哈哈,服务器第一次应答就两招都用了,既设了cookie,又url上面加了jessionid.

点击那个request the same page again, 重新查看response Header,

HTTP/1.1 200 OK
Server: Apache-Coyote/1.1
Content-Type: text/html;charset=ISO-8859-1
Content-Length: 398
Date: Sat, 06 Apr 2013 08:43:04 GMT

 

发现不同了吗,这次没有set-cookie 的header, 显然服务器已经知道了我们的浏览器不支持cookie,因为我们的这次请求中没有带cookie Header, 如下

GET /scwcd/greet.jsp;jsessionid=1EFB388FE94172438DCC2B02378EE1DA HTTP/1.1
Host: localhost:8888
User-Agent: Mozilla/5.0 (Windows NT 6.1; rv:20.0) Gecko/20100101 Firefox/20.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: en-US,en;q=0.5
Accept-Encoding: gzip, deflate
Referer: http://localhost:8888/scwcd/greet.jsp
Connection: keep-alive

 

因为网站总是从一个页面通过连接导航到其他页面,所以服务器很容易通过两次请求判断出客户端是否支持cookie.

如果我们总是在禁用cookie的情况下,总是发相同的请求localhost:8888/scwcd/greet.jsp, 那服务器就每次都创建一个新session了, 例如连发两次请求,会看到server 端有这样的输出

session with id 38704BBDADF2288B06A1EA1A2FE65444 created
session with id 1EF1F1E07A1CBEEE23848E83AE63794B created

 

问题三:

关闭浏览器窗口,为什么原来的session 不见了?

改一下上面的servlet代码,

	public void doGet(HttpServletRequest request, HttpServletResponse response)
			throws IOException {
		request.getSession();
		Cookie[] cks = request.getCookies();
		if (cks != null) {
			for (Cookie ck : cks) {
				if(ck.getName().equalsIgnoreCase("JSESSIONID")){
					System.out.println(ck.getMaxAge());
				}				
			}
		} 

	}

 

重新启用浏览器cookie, 清掉浏览器cookie,第一次请求http://localhost/scwcd/MyServlet 显示session with id 968AA6D2D673ED67A06ECA2B3F054644 created, 第二次请求相同的地址的时候发现maxage

输出结果为-1. 查一下Cookie的Javadoc就会发现原因

getMaxAge()
          Returns the maximum age of the cookie, specified in seconds, By default, -1 indicating the cookie will persist until browser shutdown.

  

如果想关掉浏览器后jsessionid 存在怎么办,很简单,我们自己改cookie即可,

		HttpSession session = request.getSession();
		if(session.isNew()){
			Cookie c = new Cookie("JSESSIONID", session.getId());
			c.setMaxAge(20 * 60);
			response.addCookie(c);
		}

 

 在servlet 3.0中就更便捷,直接改web.xml 即可

 

    <session-config>  
        <session-timeout>525600</session-timeout>   
        <cookie-config>  
            <max-age>31536000</max-age>  
        </cookie-config>  
    </session-config> 
 

 

 

 

分享到:
评论

相关推荐

    httpSession

    1. **session的创建与销毁**:讲解何时服务器会创建session,以及在什么条件下会自动销毁session,比如超时或显式调用`HttpSession.invalidate()`。 2. **session的生命周期管理**:讨论session的默认超时时间...

    HttpSession的使用

    **HttpSession详解** 在Web开发中,`HttpSession` 是一个至关重要的概念,它属于Java Servlet API的一部分,用于在客户端浏览器和服务器之间存储状态信息。当你需要在用户的不同请求之间保持某些数据时,例如购物车...

    spring websocket获取httpsession

    在Spring 4版本中,我们经常需要结合WebSocket与HttpSession来处理需要用户上下文信息的场景。本篇将详细讲解如何在Spring WebSocket中获取HttpSession。 首先,我们需要理解WebSocket与HttpSession的基本概念。...

    httpsession实现验证码登录小实例

    在本文中,我们将深入探讨如何使用Java编程语言和HttpSession接口来实现一个简单的验证码登录系统。验证码(CAPTCHA)是一种防止恶意机器人或自动化程序非法访问网站的安全机制,它要求用户输入图片上显示的一组随机...

    利用HttpSession实现Ajax请求重定向.docx

    HttpSession 实现 Ajax 请求重定向 标题:利用 HttpSession实现Ajax请求重定向 描述:如何在 Ajax 请求正常执行的情况下,实现网页重定向 标签:Ajax 重定向 HttpSession post 在本文中,我们将探讨如何使用 ...

    用户管理系统(ums)

    HttpSession session= request.getSession(); // 设置session的值 session.setAttribute("userList", list); //跳转到显示的页面,格式(得到当前页面的+要跳转的页面) response.sendRedirect(request....

    WebSocket区分不同客户端两种方法(HttpSession和@PathParam)

    HttpSession httpSession = (HttpSession) config.getUserProperties().get(HttpSession.class.getName()); } } ``` 通过这种方式,可以在WebSocket连接建立时获取到当前用户的`HttpSession`,从而获取用户的相关...

    servlet-api.jar 适用于import javax.servlet.http.HttpSession;异常

    servlet-api.jar 适用于import javax.servlet.http.HttpSession;异常 直接下载后直接导入 即可,

    HttpSession基于Redis,支持RESTful API .zip

    HttpSession基于Redis,支持RESTful API。RedisHttpSessionRedisHttpSession提供了一种将http session透明地存储在redis中的方法,从而允许多客户端共享session。特征RESTful API - RedisHttpSession 允许在标头中...

    Web_4_状态管理Cookie和HttpSession1

    状态管理的两种常见模式是Cookie和HttpSession。Cookie是一种客户端状态管理技术,它将状态信息存储在用户的浏览器中。服务器通过在HTTP响应头中添加`Set-Cookie`字段,向浏览器发送Cookie,浏览器则会在后续的请求...

    HttpSession/session,jsp,servlet——综合练习题一

    在IT行业中,尤其是在Web开发领域,`HttpSession`、`jsp`和`servlet`是三个非常重要的概念。这里我们将深入探讨这些技术,并结合一个名为"web26_session5示例1"的压缩包文件,来解析它们在实际应用中的综合运用。 ...

    HTTPSession-开源

    HTTPSession库提供了方便的方法来操作Cookie,如添加、删除、获取和更新Cookie值。这使得开发者能够轻松处理登录状态、个性化设置等需要持久化信息的场景。 2. **HTTP身份验证**: HTTP协议提供了多种身份验证机制...

    ServletHttpSession DEMO

    下面我们将深入探讨ServletHttpSession的相关知识点。 **1. HTTP协议的无状态性** HTTP协议本身是无状态的,这意味着每次客户端向服务器发送请求,服务器处理完后就不再保留任何关于这个请求的信息。为了在多个请求...

    servletapi.rar_HttpSession jar_Java jar包_javaee.jar_servletAPI

    1. **HttpSession**: HttpSession接口是Java Servlet API的一部分,它允许开发者在客户端的浏览器会话之间存储和检索数据。在Web应用中,当用户打开一个网站并进行一系列操作时,HttpSession可以帮助保持用户的登录...

    在WebSphereApplicationServerV7集群环境中管理HTTPsession.pdf

    在WebSphereApplicationServerV7集群环境中管理HTTPsession.pdf

    Web应用安全:HTTPSession.pptx

    这个 SessionID 在响应浏览器的时候会被装进 Cookie 中,从而被保存到浏览器中。之后,当用户再次访问 Servlet 时,请求中会携带着 Cookie 中的 SessionID 去访问服务器。服务器会根据这个 SessionID 去查看是否有...

    jsp有哪些内置对象?作用分别是什么?分别有什么方法?

    4. **session**:这个对象是`HttpSession`,用于存储与特定用户会话相关的数据。会话在用户打开网站并持续到关闭浏览器或会话超时。关键方法有`getAttribute()`, `setAttribute()`, `getId()`, `invalidate()`来管理...

    java使用HttpSession实现QQ访问记录

    在Java Web开发中,`HttpSession` 是一个关键的组件,用于存储客户端会话状态的信息。本示例展示了如何利用`HttpSession`来追踪QQ访问记录。以下将详细讲解实现这个功能所需的知识点: 1. **HttpSession接口**:`...

    java面试宝典

    61、什么时候用assert? 16 62、error和exception有什么区别 16 63、ArrayList和Vector的区别 16 64、Collection 和 Collections的区别 17 65、Set里的元素是不能重复的,那么用什么方法来区分重复与否呢? 是用==...

Global site tag (gtag.js) - Google Analytics