﻿<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:trackback="http://madskills.com/public/xml/rss/module/trackback/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/"><channel><title>BlogJava-Habitat Framework-文章分类-HTTP</title><link>http://www.blogjava.net/hunteva/category/10083.html</link><description>专注于Java EE企业级开发</description><language>zh-cn</language><lastBuildDate>Tue, 27 Feb 2007 12:32:19 GMT</lastBuildDate><pubDate>Tue, 27 Feb 2007 12:32:19 GMT</pubDate><ttl>60</ttl><item><title>What's session [转载]</title><link>http://www.blogjava.net/hunteva/articles/41352.html</link><dc:creator>Kerwin Weng</dc:creator><author>Kerwin Weng</author><pubDate>Sun, 16 Apr 2006 10:13:00 GMT</pubDate><guid>http://www.blogjava.net/hunteva/articles/41352.html</guid><wfw:comment>http://www.blogjava.net/hunteva/comments/41352.html</wfw:comment><comments>http://www.blogjava.net/hunteva/articles/41352.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/hunteva/comments/commentRss/41352.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/hunteva/services/trackbacks/41352.html</trackback:ping><description><![CDATA[
		<p>HTTP协议（<a href="http://www.w3.org/Protocols/">http://www.w3.org/Protocols/</a>）是“一次性单向”协议。 <br />服务端不能主动连接客户端，只能被动等待并答复客户端请求。客户端连接服务端，发出一个HTTP Request，服务端处理请求，并且返回一个HTTP Response给客户端，本次HTTP Request-Response Cycle结束。 <br />我们看到，HTTP协议本身并不能支持服务端保存客户端的状态信息。于是，Web Server中引入了session的概念，用来保存客户端的状态信息。 <br />这里用一个形象的比喻来解释session的工作方式。假设Web Server是一个商场的存包处，HTTP Request是一个顾客，第一次来到存包处，管理员把顾客的物品存放在某一个柜子里面（这个柜子就相当于Session），然后把一个号码牌交给这个顾客，作为取包凭证（这个号码牌就是Session ID）。顾客（HTTP Request）下一次来的时候，就要把号码牌（Session ID）交给存包处（Web Server）的管理员。管理员根据号码牌（Session ID）找到相应的柜子（Session），根据顾客（HTTP Request）的请求，Web Server可以取出、更换、添加柜子（Session）中的物品，Web Server也可以让顾客（HTTP Request）的号码牌和号码牌对应的柜子（Session）失效。顾客（HTTP Request）的忘性很大，管理员在顾客回去的时候（HTTP Response）都要重新提醒顾客记住自己的号码牌（Session ID）。这样，顾客（HTTP Request）下次来的时候，就又带着号码牌回来了。 <br />我们可以看到，Session ID实际上是在客户端和服务端之间通过HTTP Request和HTTP Response传来传去的。 </p>
		<p>我们看到，号码牌（Session ID）必须包含在HTTP Request里面。关于HTTP Request的具体格式，请参见HTTP协议（<a href="http://www.w3.org/Protocols/">http://www.w3.org/Protocols/</a>）。这里只做一个简单的介绍。 <br />在Java Web Server（即Servlet/JSP Server）中，Session ID用jsessionid表示（请参见Servlet规范）。 <br />HTTP Request一般由3部分组成： <br />（1）Request Line <br />这一行由HTTP Method（如GET或POST）、URL、和HTTP版本号组成。 <br />例如，GET <a href="http://www.w3.org/pub/WWW/TheProject.html">http://www.w3.org/pub/WWW/TheProject.html</a> HTTP/1.1 <br />GET <a href="http://www.google.com/search?q=Tomcat">http://www.google.com/search?q=Tomcat</a> HTTP/1.1 <br />POST <a href="http://www.google.com/search">http://www.google.com/search</a> HTTP/1.1 <br />GET <a href="http://www.somsite.com/menu.do;jsessionid=1001">http://www.somsite.com/menu.do;jsessionid=1001</a> HTTP/1.1 </p>
		<p>（2）Request Headers <br />这部分定义了一些重要的头部信息，如，浏览器的种类，语言，类型。Request Headers中还可以包括Cookie的定义。例如： <br />User-Agent: Mozilla/4.0 (compatible; MSIE 5.5; Windows NT 5.0) <br />Accept-Language: en-us <br />Cookie: jsessionid=1001 </p>
		<p>（3）Message Body <br />如果HTTP Method是GET，那么Message Body为空。 <br />如果HTTP Method是POST，说明这个HTTP Request是submit一个HTML Form的结果， <br />那么Message Body为HTML Form里面定义的Input属性。例如， <br />user=guest <br />password=guest <br />jsessionid=1001 <br />主意，如果把HTML Form元素的Method属性改为GET。那么，Message Body为空，所有的Input属性都会加在URL的后面。你在浏览器的URL地址栏中会看到这些属性，类似于 <br /><a href="http://www.somesite/login.do?user=guest&amp;password=guest&amp;jsessionid=1001">http://www.somesite/login.do?user=guest&amp;password=guest&amp;jsessionid=1001</a></p>
		<p>从理论上来说，这3个部分（Request URL，Cookie Header, Message Body）都可以用来存放Session ID。由于Message Body方法必须需要一个包含Session ID的HTML Form，所以这种方法不通用。 <br />一般用来实现Session的方法有两种： <br />（1）URL重写。 <br />Web Server在返回Response的时候，检查页面中所有的URL，包括所有的连接，和HTML Form的Action属性，在这些URL后面加上“;jsessionid=XXX”。 <br />下一次，用户访问这个页面中的URL。jsessionid就会传回到Web Server。 <br />（2）Cookie。 <br />如果客户端支持Cookie，Web Server在返回Response的时候，在Response的Header部分，加入一个“set-cookie: jsessionid=XXXX”header属性，把jsessionid放在Cookie里传到客户端。 <br />客户端会把Cookie存放在本地文件里，下一次访问Web Server的时候，再把Cookie的信息放到HTTP Request的“Cookie”header属性里面，这样jsessionid就随着HTTP Request返回给Web Server。 </p>
		<p>我们来看Tomcat5的源代码如何支持jsessionid。 <br />org.apache.coyote.tomcat5.CoyoteResponse类的toEncoded()方法支持URL重写。 <br />String toEncoded(String url, String sessionId) { <br />… <br />StringBuffer sb = new StringBuffer(path); <br />if( sb.length() &gt; 0 ) { // jsessionid can't be first. <br />sb.append(";jsessionid="); <br />sb.append(sessionId); <br />} <br />sb.append(anchor); <br />sb.append(query); <br />return (sb.toString()); <br />} </p>
		<p>我们来看org.apache.coyote.tomcat5.CoyoteRequest的两个方法configureSessionCookie() <br />doGetSession()用Cookie支持jsessionid. </p>
		<p>/** <br />* Configures the given JSESSIONID cookie. <br />* <br />* @param cookie The JSESSIONID cookie to be configured <br />*/ <br />protected void configureSessionCookie(Cookie cookie) { <br />… <br />} </p>
		<p>HttpSession doGetSession(boolean create){ <br />… <br />// Creating a new session cookie based on that session <br />if ((session != null) &amp;&amp; (getContext() != null) <br />&amp;&amp; getContext().getCookies()) { <br />Cookie cookie = new Cookie(Globals.SESSION_COOKIE_NAME, <br />session.getId()); <br />configureSessionCookie(cookie); <br />((HttpServletResponse) response).addCookie(cookie); <br />} <br />… <br />} </p>
		<p>Session的典型应用是存放用户的Login信息，如用户名，密码，权限角色等信息，应用程序（如Email服务、网上银行等系统）根据这些信息进行身份验证和权限验证</p>
<img src ="http://www.blogjava.net/hunteva/aggbug/41352.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/hunteva/" target="_blank">Kerwin Weng</a> 2006-04-16 18:13 <a href="http://www.blogjava.net/hunteva/articles/41352.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item></channel></rss>