浏览器与服务器之间交互,通过JSESSIONID来维护统一会话:
换就话说就是,使用浏览器提交请求时,服务器收到请求,如果请求有带上JSESSIONID,那么根据这个JSESSIONID去找对应的session,如果找不到则通过调用request.getSession()生成一个JSESSIONID号,(在服务器中我们可能会往Session中放入我们的数据,JSESSIONID是用来找对应的Session),且自动放到请求头,然后返回给浏览器。浏览器下次发请求,去请求其他资源,或者原来的资源的时候,会默认带上这个从服务器返回来的Jsessionid。如果禁用cookie。浏览器会对url重写的方式放入JSESSIONID.
直接访问jsp页面时,会自动生成一个JSESSIONID,但是访问servlet时不会自动生成JSESSIONID,需要通过request.getSession()来生成JSESSIONID.
上面所说的都是浏览器与服务器之间的会话维护。但是现实中我们的客户端可不单单只有浏览器:我们的客户端可能是电脑上的软件,手机上的软件,以及各种各样的客户端。此时怎么来维护会话呢。
答案当然是模拟浏览器提交请求啊:浏览器是自动提交,那我们其他的客户端就手动提交嘛。
我们要提交啥:提交JSESSIONID
JSESSIONID怎么来:服务器自动生成的,我们要在客户端那里将它拿出来。
怎么提交:通过cookie提交
代码该咋写:思路是:第一次提交请求,服务器生成JSESSIONID号,并且往Session中放了点数据,然后返回,客户端获取JSESSIONID,将JSESSIONID保存起来(手机端可以用文件,sqline,或直接保存在内存中),下次再访问资源时可以从文件中将JSESSIONID读出来,然后放到cookie中,提交,服务器拿到请求,根据JSESSIONID,找到对应的Session,从中获取第一次设定的Session中的值。
直接上代码:
服务器端有两个处理请求的函数
第一个处理请求的函数:把某些数据放进session中
@RequestMapping("/respon.do")
@ResponseBody
public String respon(HttpServletResponse response,HttpServletRequest request) throws IOException
{
System.out.println(request.getRequestURI());
System.out.println(request.getHeader("set-cookie"));
System.out.println(request.getRequestedSessionId());
request.getSession().setAttribute("user","a");
return "xixixixi";
}
第二个处理请求的函数:取出上个请求中Session中的值
@RequestMapping("/respontwo.do")
public void respontwo(HttpServletResponse response,HttpServletRequest request) throws IOException
{
System.out.println(request.getRequestURI());
System.out.println(request.getRequestedSessionId());
System.out.println(request.getRequestedSessionId());
System.out.println(request.getSession().getAttribute("user"));
response.getWriter().print("xzf");
}
然后是客户端:先访问第一个请求,再访问第二个请求
@Test
public void testHttp() throws IOException
{
URL url = new URL("http://localhost:8080/weibo/public/respon.do?"); //第一个请求
URLConnection rulConnection = url.openConnection();
HttpURLConnection httpUrlConnection = (HttpURLConnection) rulConnection;
httpUrlConnection.setDoOutput(true);
httpUrlConnection.setDoInput(true);
httpUrlConnection.setUseCaches(false);
httpUrlConnection.setRequestProperty("Content-type", "application/x-java-serialized-object");
httpUrlConnection.setRequestMethod("POST");
httpUrlConnection.connect();
String cookieval = httpUrlConnection.getHeaderField("set-cookie"); //获取http头的内容
String sessionid = cookieval.substring(0, cookieval.indexOf(";")); //获取JSESSIONID(供第二个请求使用)
System.out.print(cookieval);
Map<String, String> hm=HttpUtil.getHttpResponseHeader(httpUrlConnection);
for (Map.Entry<String, String> entry : hm.entrySet()) {
String key = entry.getKey() != null ? entry.getKey() + ":" : "";
System.out.println(key + entry.getValue());
}
InputStream in=httpUrlConnection.getInputStream();
StringBuffer out=new StringBuffer();
byte[] b=new byte[1024];
int n=-1;
while((n=in.read(b))!=-1)
{
out.append(new String(b,0,n));
}
System.out.println(out.toString());
httpUrlConnection.disconnect();
URL urlw = new URL("http://localhost:8080/weibo/public/respontwo.do"); //第二个请求
URLConnection rulConnections = urlw.openConnection();
HttpURLConnection httpUrlConnections = (HttpURLConnection) rulConnections;
httpUrlConnections.setDoOutput(true);
httpUrlConnections.setDoInput(true);
httpUrlConnections.setUseCaches(false);
httpUrlConnections.setRequestProperty("Content-type", "application/x-java-serialized-object");
httpUrlConnections.setRequestMethod("POST");
httpUrlConnections.setRequestProperty("cookie",sessionid); //将从第一个请求获取到的sessionid通过cookie发送至服务器
httpUrlConnections.connect();
System.out.print(cookieval);
Map<String, String> hms=HttpUtil.getHttpResponseHeader(httpUrlConnections);
for (Map.Entry<String, String> entry : hms.entrySet()) {
String key = entry.getKey() != null ? entry.getKey() + ":" : "";
System.out.println(key + entry.getValue());
}
InputStream ins=httpUrlConnections.getInputStream();
StringBuffer outs=new StringBuffer();
byte[] bs=new byte[1024];
int ns=-1;
while((ns=ins.read(bs))!=-1)
{
outs.append(new String(bs,0,ns));
}
System.out.println(outs.toString());
httpUrlConnections.disconnect();
}
代码中调用了取出http头信息的函数:
public class HttpUtil {
public static Map<String, String> getHttpResponseHeader(
HttpURLConnection http) throws UnsupportedEncodingException {
Map<String, String> header = new LinkedHashMap<String, String>();
for (int i = 0;; i++) {
String mine = http.getHeaderField(i);
if (mine == null)
break;
header.put(http.getHeaderFieldKey(i), mine);
}
return header;
}
这样的结果是,第一个请求设置的Session,在第二个请求中能被读出来。
完毕。