状态管理
什么是状态管理
将浏览器与web服务器之间的多次交互作为一个整体来处理,并且将多次交互所涉及的数据(即状态)保存下来。
cookie
什么是cookie ?
就是服务器临时保存在浏览器端少量的数据
工作基本原理:
当浏览器访问服务器时,服务器可以将少量数据以 set-cookie消息头的方式发给浏览器
浏览器会将这些数据临时保存下来。(时间有限制)
当浏览器再次访问服务器,会将之前保存的这些数据以cookie消息头的方式发送给服务器。
添加cookie
创建一个cookie对象
Cookie c = new Cookie(String name,String value)
response.addCookie(c);
还可以一次加很多个cookie
例如:
public class AddCookieServlet extends HttpServlet {
public void service(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
Cookie c = new Cookie("username","Recar");
response.addCookie(c);
}
然后服务器读取cookie
Cookie 【】 request.getCookies();
cookie可能会有多个。
String cookie.getName();
String cookie.getValue();
public void service(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
response.setContentType("text/html");
PrintWriter out = response.getWriter();
Cookie [] cookies = request.getCookies();
//要注意,该方法有可能返回空,
if(cookies!=null){
for(int i=0;i<cookies.length;i++){
out.print("Name:"+cookies[i].getName());
out.print("<br>");
out.print("Value:"+cookies[i].getValue());
}
}
else{
out.println("找不到任何的Cookie");
}
out.close();
}
Cookie编码问题
Cookie里只能保存合法的ascii码字符
对于中文,需要将其转换成相应的ascii字符的表示形式
URLEncoder.encode
URLEncoder.decode
package test;
import java.io.UnsupportedEncodingException;
import java.net.URLDecoder;
import java.net.URLEncoder;
public class test {
public static void main(String[] args) throws UnsupportedEncodingException {
String str ="哈利波特";
String str2 = URLEncoder.encode(str,"utf-8");
String str3 = URLDecoder.decode(str2,"utf-8");
System.out.println(str2);
System.out.println(str3);
}
}
Cookie c = new Cookie("username",URLEncoder.encode("Recar","utf-8"));
Cookie [] cookies = request.getCookies();
//要注意,该方法有可能返回空,
if(cookies!=null){
for(int i=0;i<cookies.length;i++){
out.print("Name:"+URLDecoder.decode(cookies[i].getName(),"utf-8"));
out.print("<br>");
out.print("Value:"+URLDecoder.decode(cookies[i].getValue(),"utf-8"));
}
}
else{
out.println("找不到任何的Cookie");
}
out.close();
就用编码
URLEncoder.encode(str,str);
URLDecoder.decode(str2,str);
添加cookie时,建议最好统一编码处理
cookie生成时间问题
setMaxAge(int seconds);
默认情况下,浏览器会把cookie保存在内存里。关闭浏览器cookie就没了。
那个setMaxAge();单位是秒
seconds可以大于小于等于0
设置保存一年:365*24*60*60
大于0:浏览器会将cookie保存在硬盘上,就算关机也不会没。
如果超过了指定的时间,则cookie会被删除。
小于0:默认值 就是把cookie放在内存中
等于0:删除cookie
更改cookie
就是添加一个name一样的cookie。改变不同的value
删除cookie
比如要删除一个名为 cart的cookie
Cookie c = new Cookie(“cart”,””);
c.setMaxAge(0);
response.addcookie(c);
新的会把老的cookie替代,然后又设置生成时间为0.即给其删除
Cookie c = new Cookie("username",URLEncoder.encode("Recar","utf-8"));
c.setMaxAge(40);
response.addCookie(c);
40s后,findcookie就没了。
练习: 写一个Find_addCookieServlet,先查看有没有一个名称为“Recaunivs”的cookie,如果有,则显示cookie的值,如果没有,则创建。
package web;
import java.io.IOException;
import java.io.PrintWriter;
import javax.servlet.ServletException;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
public class Find_AddCookieServlet extends HttpServlet {
public void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
response.setContentType("text/html");
PrintWriter out = response.getWriter();
Cookie[] cookies = request.getCookies();
if(cookies!=null){
for(int i=0;i<cookies.length;i++){
if(cookies[i].getValue().equals("Recaunivs")){
out.print("name:"+cookies[i].getName());
out.print("<br>");
out.print("value:"+cookies[i].getValue());
}//if
else{
//cookie不是Recaunivs,设置其cookie
Cookie c = new Cookie("name","Recaunivs");
c.setMaxAge(60);
response.addCookie(c);
}//else
}//for
}//if
else{
//cookie不是Recaunivs,设置其cookie
Cookie c = new Cookie("name","Recaunivs");
c.setMaxAge(60);
response.addCookie(c);
}//else
out.close();
}
}
路径问题
什么是cookie的路径问题
浏览器在向服务器上的某个地址发请求时,会比较该地址是否符合cookie的路径的要求,只有符合条件的cookie才会被发送出去。
cookie的默认的路径:
等于添加该cookie的组件(servlet/jsp)的路径
比如 cookie1/test01/cookie.jsp添加了一个名称为”cart”的cookie,则该cookie有一个默认的路径(/cookie/test01)
然后写一个jsp用来显示cookie
路径为:
cookie1/findcookie.jsp 这个是不会返回cookie的
但是
cookie1/test01/findcookie.jsp 会返回cookie!!!
在创建一个jsp在cookie1下的test01的另一个文件夹的findcookie也能返回cookie!!!
则匹配规则:
请求地址必须等于cookie的路径或者是其子路径。
session(会话)
什么是session?
服务器端为维护状态而创建的一个特殊的对象
工作原理:
浏览器访问服务器时,服务器会创建一个session对象(该对象有一个唯一的ID,称之为sessionId),服务器会将sessionId以cookie的方式发送给浏览器
浏览器再次访问服务器时,会将sessionId以cookie的方式发送过来,服务端可以利用sessionId找到对应的session对象
如何获得session对象?
两种方式
方式一:
HttpSession s = request.getSession(true/false);
当参数值为true:
getSession方法会先查看请求当中有没有sessionId
如果没有,则创建一个session对象。
如果有sessionId,则依据该sessionId查找对应的session对象。
如果找到了则返回,找不到则创建一个新的session对象。
当参数值为false:
getSession方法会先查看请求当中有没有sessionId
如果没有,则返回null。
如果有sessionId,则依据该sessionId查找对应的session对象。
如果找到了则返回,找不到则返回null。
大部分情况下使用true
方式二:
HttpSession s = request.getSession();
不写任何参数的默认就是参数值为true
public void service(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
response.setContentType("text/html;charset=utf-8");
PrintWriter out = response.getWriter();
//获得一个session
HttpSession s = request.getSession();
//获取sessionId
String sessionid = s.getId();
System.out.println(sessionid);
out.close();
}
sessionId:!!!就是cookie的值!!!
因为参数是true,有就还是那个不会改变sessionId
session常用的方法:
String getId() 获得sessionId
setAttribute(String name,Object obj)
//该方法有可能返回null 绑定,然后根据绑定获取绑定对象
Object getAttribute(String name)
注意返回的是一个对象。
removeAttribute(String name)
//解除绑定
例子: 计算访问次数:
public void service(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
response.setContentType("text/html;charset=utf-8");
PrintWriter out = response.getWriter();
//获得一个session
HttpSession s = request.getSession();
//获取sessionId
String sessionid = s.getId();
System.out.println(sessionid);
Integer count = (Integer) s.getAttribute("count");
if(count==null){
//说明是第一次访问
count = 1;
}else{
//不是第一次访问
count++;
}
s.setAttribute("count", count);
out.print("你是第:"+count+"次访问");
out.close();
}
session超时
什么是session超时
服务器会将空闲时间过长的session对象删除掉。
默认的超时时间限制一般是30分钟
以Tomcat为例:
conf文件夹下的web.xml
session-timeout设置是设置默认超时时间
不建议改。
还有setMaxInActiveInterval(int seconds)单位为秒
用session对象调用setMaxInActiveInterval(40)
就是说如果不活动超过40s就删除。
也就是之前的记录访问次数的那个,期间超过40s就会重新计算了。
删除session
invalidate();
直接session调用invalidate()
练习: 使用cookie来实现统计用户是第几次访问某个servlet
servlet先去读有没有一个名叫count的cookie。
如果没有的话说明是第一次
如果有的话就把cookie的值读出来加1.再发送给浏览器
package web;
import java.io.IOException;
import java.io.PrintWriter;
import javax.servlet.ServletException;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
public class cookiecount extends HttpServlet {
public void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
response.setContentType("text/html;charset=utf-8");
PrintWriter out = response.getWriter();
//先去读取有没有一个叫count的cookie。有就取出值加1,没有就创建并设置为1
Cookie[] cookies = request.getCookies();
if(cookies!=null){
for(int i=0;i<cookies.length;i++){
if(cookies[i].getName().equals("count")){
Integer count = Integer.valueOf(cookies[i].getValue());
count++;
Cookie countcookie = new Cookie("count",String.valueOf(count));
countcookie.setMaxAge(365*24*60*60);
response.addCookie(countcookie);
out.print("你是第:"+count+"次访问!");
break;
}
}
}
else{
Cookie c = new Cookie("count","1");
out.print("你是第1次访问");
response.addCookie(c);
}
out.close();
}
}
关了浏览器还是可以~