如何解决HTTP协议无状态问题
HTTP是无状态的协议,客户每次读取web页面时,服务器都打开新的连接,而且服务器也不会自动维护客户的上下文信息
那么要怎么才能在多次请求之间共享信息呢(比如实现网上商店中的购物车)?
服务器端如何判断一个客户的分时段的连接是不是属于同一个客户?
session和cookie就是为解决HTTP协议的无状态采用的两种解决方案
可以采用session将信息保存在服务器端解决
可以采用cookie将信息保存在客户端解决
Session和Cookie的原理
Cookie:发给顾客一张卡片,上面记录着消费的数量,一般还有个有效期限。每次消费时,如果顾客出示这张卡片,则此次消费就会与以前或以后的消费相联系起来。这种做法就是在客户端保持状态。 【卡上记录所有信息,而店家只认卡不认人。】
session:发给顾客一张会员卡,除了卡号之外什么信息也不纪录,每次消费时,如果顾客出示该卡片,则店员在店里的纪录本上找到这个卡号对应的纪录添加一些消费信息。这种做法就是在服务器端保持状态。 【只记用户ID,而ID的详细记录放在店家的数据库里;每次凭ID检索服务器的记录。】
@Override
protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//[1]接受页面(前台的页面)的数据
String uname = req.getParameter("uname");
String pwd = req.getParameter("pwd");
String ch = req.getParameter("ch"); //[2]数据的处理--连接数据库作比较返回结果
boolean flag=false;
if("尚学堂".equals(uname)&&"123".equals(pwd)){
flag=true;
}
//[3]根据返回的结果给用户做出响应
if(flag){
/**********使用Cookie记住密码的操作***********/
//把uname 中文的字符串进行UTF-8格式的编码
String encode = URLEncoder.encode(uname, "utf-8");
System.out.println(encode);
//[1]申请卡片 填写卡片的信息
Cookie cookie=new Cookie("u",encode);
Cookie cookie2=new Cookie("p",pwd);
//[2]规定卡片的使用规则
//指定卡片的使用范围 --/ 在当前服务器内都有效 /servlet04--只在当前项目中有效
cookie.setPath("/");
cookie2.setPath("/");
//设置Cookie的有效的时间
if("yes".equals(ch)){
//勾选了记住我操作
//设置cookie 有效的时间
cookie.setMaxAge(60*60*24*10);
cookie2.setMaxAge(60*60*24*10);
}else{
cookie.setMaxAge(0);
cookie2.setMaxAge(0);
}
//[3]把卡片交给到用户手中
resp.addCookie(cookie);
resp.addCookie(cookie2);
//登录成功
resp.sendRedirect("/servlet04/success.jsp");
}else{
//登录失败
req.setAttribute("msg","用户名和密码不匹配");
req.getRequestDispatcher("/login.jsp").forward(req,resp);
}
}
|
<body>
<%
String uname="";
String pwd="";
String ch="";
//获得所有本地Cookie 内容
Cookie[] cookies = request.getCookies();
if(cookies!=null){
for(Cookie c :cookies){
if("u".equals(c.getName())){
// c--代表的就是用户名对应的Cookie对象
uname= URLDecoder.decode(c.getValue(),"utf-8");
ch="checked";
}
if("p".equals(c.getName())){
// c--代表的就是密码对应的Cookie对象
pwd= c.getValue();
}
}
} %>
<h3>登录页面</h3>
<form action="DoLogin">
<p>
用户名:<input type="text" id="uname" name="uname" value="<%=uname%>"/>
</p>
<p>
密码:<input type="text" name="pwd" value="<%=pwd%>"/>
</p>
<p>
<input type="checkbox" name="ch" value="yes" <%=ch%> />记住密码
</p>
<p>
<input type="submit" value="登录"/>
</p>
</form>
</body>
|
Session 的原理
需求说明:
完成用户登录功能
登录成功后跳到成功页面,显示用户名
登录失败可以跳回登录页面
登录成功后后续操作均能显示当前登录的用户名
//[A]获得session对象
HttpSession session = req.getSession();
//[B]把对应的值保存到session中
session.setAttribute("uname",uname);
|
Session 的失效时机
[1]Session.invalidate()
[2]超过最大非活动间隔时间
[3]关闭浏览器(该方式没有立刻结束session)
session失效的方式
[1]手动注销sesison
session.invalidate();
[2]超过session 活动的有效时间
Session 最大活动时间是30分钟,我们可以更改这个默认的时间
A、更改TomCat中web.xml中的配置
影响的是:所有项目中的所有session
<session-config>
<session-timeout>30</session-timeout>
</session-config>
B、更改自己项目的web.xml
影响的是:当前项目的所有session
<session-config>
<session-timeout>40</session-timeout>
</session-config>
C、更改当前项目的当前session 失效的时间
session.setMaxInactiveInterval(10);
[3]关闭浏览器
这种红方式只是把浏览器中保存到cookie 中的Jsession 给清除了
保存到服
务器中的session并没有真正的消失 |
Session和Cookie的区别
cookie数据存放在客户端,session数据放在服务器上(sessionid可以通过cookie保存在客户端,也可以使用URL重写方式)
cookie不是很安全(可以加密),别人可以分析存放在本地的COOKIE并进行COOKIE欺骗,考虑到安全应当使用session
session会在一定时间内保存在服务器上。当访问增多,会比较占用你服务器的性能,考虑到减轻服务器性能方面,应当使用COOKIE
单个cookie在客户端的限制是3K,就是说一个站点在客户端存放的COOKIE不能3K。
Cookie的数据都以字符串的形式保存。Session中可以保存对象信息。
典型使用
Cookie:记住我 最近浏览商品 网页皮肤
session:登录信息 购物车(也可以使用Cookie)