javaWeb 学习日记(9)——--session

Session cookie

基础知识:

  • session通过SessionID来区分不同的客户,session是以cookie或URL重写为基础的,默认使用cookie来实现,系统会创造一个名为JSESSIONID的输出cookie ,这称之为session cookie,以区别persistent cookies(也就是我们通常所说的cookie),session cookie是存储于浏览器内存中的,并不是写到硬盘上的,通常看不到JSESSIONID,但是当把浏览器的cookie禁止后,web服务器会采用URL重写的方式传递Sessionid,这时地址栏看到
  • session cookie针对某-次会话而言,会话结束session cookie也就随着消失了,而persistent cookie只是存在于客户端硬盘上的一段文本。
  • 关闭浏览器,只会是浏览器端内存里的session cookie消失,但不会使保存在服务器端的session对象消失,同样也不会使已经保存到硬盘上的持久化cookie消失。

HttpSession 的生命周期

1. 什么时候创建HttpSession 对象
①对于JSP:是否浏览器访问服务端的任何一个JSP, 服务器不一定创建一 个HttpSession对象

若当前的JSP是客户端访问的当前WEB应用的第一 个资源,且JSP的page指定的session 属性值为false,则服务器就不会为JSP创建-个HttpSession对象;


若当前JSP不是客户端访问的当前WEB应用的第一个资源,且其他页面已经创建一个HttpSession对象,则服务器就不会为JSP创建-个HttpSession对象

②对于Serlvet:若Serlvet是客户端访问的第一-个WEB应用的资源,则只有调用了request . getSession()或request . getSession(true)才会创建HttpSession对象

2. page指令的session="false"
指当前JSP页面禁用session 隐含变量!但可以使用其他的显式的HttpSession 对象

3. 在servlet 中获取HttpSession 对象

request . getSession(boolean create):

create为false,若没有和当前JSP页面关联的HttpSession对象,则返回null;若有,则返回true
create为true, -定返回一个HttpSession对象。若没有和当前JSP页面关联的HttpSession对象,则服务器创建一个新的HttpSession对象返回,若有,直接返回关联的。

request . getSession(): 等同于request . getSession(true)

4.什么时候销毁HttpSession对象:
①直接调用HttpSession 的invalidate() 方法:该方法使HttpSession 失效

②服务器卸载了当前WEB应用。

③超出HttpSession的过期时间。
>设置HttpSession的过期时间: session. setMaxInactiveInterval(5);单位秒
>在web. xml文件中设置HttpSession的过期时间:单位为分钟.

<session- config>
	<session-t imeout >30</sess ion- timeout>
</session- config>

④.并不是关闭了浏览器就销毁了HttpSession.

HttpSession 接口中的方法

  • getId
    得到session的 id
  • getCreateTime
    得到创建时间
  • getLastAccessdTIme
    得到上次访问时间
  • setMaxInactiveIntever
    设置生命周期
  • getMaxInactiveIntever
    得到生命周期
  • isNew
    判断当前session 是不是新建的
  • invalidate
    使session 失效
  • getServletContext
    得到上下文
  • setAttribute
    设置 属性 attribute
  • getAttribute
    得到属性 attribute
  • removeAttribute
    移除属性attribute
  • getAttriuteNames
    得到属性列
案例 登陆界面

login.jsp 中

<body>
 IsNew:<%= session.isNew() %>
 <br><br>
 SessionID:<%= session.getId() %>
 <br><br>
 SessionCreatTime<%= new Date(session.getCreationTime()) %>
 <br><br>
 SessionLastAccessTime:<%= new Date(session.getLastAccessedTime()) %>
 <br><br>
 SessionMaxINactiveInterval:<%= session.getMaxInactiveInterval() %>
 <br><br>
 <%
  Object name = session.getAttribute("userName");
  if(name == null){
   name = "";
  }
 %>
 <form action="hello.jsp" method="post">
  UserName:<input type="text" name="userName" value=<%= name %>>
  <input type="submit" name = "submit" value = "Submit">
 </form>
</body>
</html>

hello.jsp中

<body>
 IsNew:<%= session.isNew() %>
 <br><br>
 SessionID:<%= session.getId() %>
 <br><br>
 SessionCreatTime<%= new Date(session.getCreationTime()) %>
 <br><br>
 SessionLastAccessTime:<%= new Date(session.getLastAccessedTime()) %>
 <br><br>
 SessionMaxINactiveInterval:<%= session.getMaxInactiveInterval() %>
 <br><br>
 Hello: <%= request.getParameter("userName") %>
 <br><br>
 <%
  session.setAttribute("userName", request.getParameter("userName"));
 %>
 <a href="logIn.jsp">重新登陆</a>
 &nbsp;
 <a href="logout.jsp">注销</a>
</body>

logout.jsp 中

<body>
已推出登陆
<br><br>
<%
 session.invalidate();
%>
<a href="sigIn.jsp">返回登陆</a>
</body>

效果图
在这里插入图片描述

利用URL 重写实现session 跟踪

Servlet规范中引入了一种补充的会话管理机制,它允许不支持Cookie的浏览器也可以与WEB服务器保持连续的会话。这种补充机制要求在响应消息的实体内容中必须包含下-次请求的超链接,并将会话标识号作为超链接的URL地址的一个特殊参数。

将会话标识号以参数形式附加在超链接的URL地址后面的技术称为URI重写。

<form action="<%= response.encodeURL("hello.jsp")%>" method="post" >
	userName:
	<input type="text" name="username">
	<input type="submit" name="submit" value="Submit">
</fomr>

1.关于 / :代表当前WEB应用的根目录,也可以代表WEB站点的根目录的情况

  1. / 如果交给浏览器解析,则代表WEB站点的根目录,如果交给WEB服务器解析则代表当前WEB应用的根目录

(1)代表当前WEB应用的根目录:在web.xml文件中,映射路径;请求的转发
(2)代表WEB站点的根目录:超链接的href 属性,请求重定向中的 /

2.关于绝对路径:

1).写绝对路径肯定不会发生问题。而写相对路径则可能会发生问题
2 ).所谓绝对路径:相对于当前WEB应用的路径.在/代表WEB站点的根目录,需要在前面加上contextPath

response.sendRedirect(request.getContextPath0 + "/check/index.jsp");
<form action=" <%= request.getContextPath0 %> /checkCodeServlet" method="post">
request.getRequestDispatcher("/di/m.jsp".forward(request, response);

3.处理重复提交的基本思想:

  1. 重复提交的情况:
    ①在表单提交到一个Servlet, 而Servlet又通过请求转发的方式响应一个JSP(HTML) 页面,此时地址栏还保留着Serlvet的那个路径,在响应页面点击"刷新"
    ②在响应页面没有到达时重复点击"提交按钮" .
    ③点击"返回",再点击"提交"
  2. 不是重复提交的情况:点击"返回",“刷新” 原表单页面,再"提交”.
  3. 如何避免表单的重复提交:
    在表单中做-个标记, 提交到Servlet时,检查标记是否存在且是否和预定义的标记致,若一致,则受理请求,并销毁标记,若不一致或没有标记,则直接响应提示信息: “重复 提交”
1仅提供一-个隐藏域: <input type= "hidden" name="token" value="atguigu"/>.
 行不通:没有方法清除固定的请求参数.
 2把标记放在request 中。
 行不通,因为表单页面刷新后,request 已经被销毁,再提交表单是一个新的request .
 3把标记放在session 中.可以!

解决方案

在原表单页面,生成一个随机值token
在原表单页面,把token值放入session 属性中
在原表单页面,把token值放入到隐藏域中.


在目标的Servlet中:获取session和隐藏域中的token值
比较两个值是否一-致:若-致,受理请求,且把session域中的token 属性清除
若不-致,则直接响应提示页面: “重复提交”

案例 表单重复提交

form.jsp 中

<body>
 <%
  //得到一个时间
  String token = new Date().getTime()+"";
  //将 token 放在session 的属性中
  request.getSession().setAttribute("token", token);
 %>
 <form action="<%= request.getContextPath() %>/formServlet" method="post">
  UserName:
  <input type="text" name="name"/>
  <input type="submit" name="submit" value="Submit"/> 
  <input type="hidden" name="tokenValue" value="<%= token %>"/>
 </form>

formServlet 中

@WebServlet("/formServlet")
public class FormServlet extends HttpServlet {
 private static final long serialVersionUID = 1L;
 protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
  //得到一个 session
  HttpSession session = request.getSession();
  //得到session 中的 token 和 提交表单中的 tokenValue
  String token = (String) session.getAttribute("token");
  String tokenValue = request.getParameter("tokenValue");
  //打印token 和 tokenvalue
  System.out.println(token);
  System.out.println(tokenValue);
  //若token 为空或者 两个不相等 则返回错误界面 
  //相等则删除 session 中的tooken 
  if(token!=null && token.equals(tokenValue)) {
   session.removeAttribute("token");
  }else {
   response.sendRedirect(request.getContextPath()+"/preventRepeatSubmit/error.jsp");
   return ;
  }
  //提交成功
  request.getRequestDispatcher("/preventRepeatSubmit/success.jsp").forward(request, response);
 }
}

successful 和 error 省略

练习 简单购物车

在这里插入图片描述
process1.jsp 中

<body>
 <h4>Step1:选择要购买的书籍</h4>
 <%= request.getContextPath() %>
 <form action="<%= request.getContextPath() %>/controlServlet1" method="post">
  <table border="1px" cellpadding="10px" cellspacing="0px">
   <tr>
    <td>书名</td>
    <td>购买</td>
   </tr> 
   <tr>
    <td>Java</td>
    <td><input type="checkbox" name="book" value="Java"></td>
   </tr>
   <tr>
    <td>Oracle</td>
    <td><input type="checkbox" name="book" value="Oracle"></td>
   </tr>
   <tr>
    <td>JavaWeb</td>
    <td><input type="checkbox" name="book" value="JavaWeb"></td>
   </tr> 
   <tr>
    <td>struts</td>
    <td><input type="checkbox" name="book" value="struts"></td>
   </tr>
   <tr>
    <td  colspan="2"><input type="submit" name = "submit" value="submit"></td>
   </tr>
  </table>
 </form>
</body>

controlServlet1.java中

@WebServlet("/controlServlet1")
public class ControlServlet1 extends HttpServlet {
 private static final long serialVersionUID = 1L;
 protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
  //得到书名
  String[] books = request.getParameterValues("book");
  //将books 放在session 的 attribute 中
  request.getSession().setAttribute("books", books);
  //请求重定向到 process2.jsp 中
  response.sendRedirect(request.getContextPath() + "/shoppingCart/process2.jsp");
 }
}

process2.jsp 中

<body>
 <h4>Step2:输入寄货地址和信用卡信息</h4>
 <form action="<%= request.getContextPath() %>/controlServlet2" method="post">
  <table border="1" cellpadding="10" cellspacing="0">
   <tr>
    <td colspan="2">基本信息</td>
   </tr>
   <tr>
    <td>姓名信息</td>
    <td><input type="text" name="name" value=""/></td>
   </tr>
   <tr>
    <td>寄送地址</td>
    <td><input type="text" name="address" value=""/></td>
   </tr>
   <tr>
    <td colspan="2">信用卡信息</td>
   </tr>
   <tr>
    <td>种类</td>
    <td>
     <input type="radio" name="cardType" value="Visa"/>Visa
     <input type="radio" name="cardType" value="Master"/>Master 
    </td>
   </tr>
   <tr>
    <td>卡号</td>
    <td><input type="text" name="card"/></td>
   </tr>
   <tr>
    <td colspan="2"><input type="submit" name="submit" value="Submit"/></td>
   </tr>
  </table>
 </form>
</body>

contorlServlet2.java 中

@WebServlet("/controlServlet2")
public class ControlServlet2 extends HttpServlet {
 private static final long serialVersionUID = 1L;
 protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
  // 得到 name address cartType card
  String name = request.getParameter("name");
  String address = request.getParameter("address");
  String cardType = request.getParameter("cardType");
  String card = request.getParameter("card");
  Customer customer = new Customer(name, address, cardType, card);
  //将customer 添加到session 中
  request.getSession().setAttribute("customer", customer);
  //重定向到 process3.jsp
  response.sendRedirect(request.getContextPath() + "/shoppingCart/process3.jsp");
 }
}

process3.jsp 中

<body>
 <h4>Step3:订单确定</h4>
 <%
  Customer customer = (Customer)session.getAttribute("customer");
  
 %>
 <table border="1" cellpadding="10" cellspacing="0">
   <tr>
    <td>顾客姓名</td>
    <td><%= customer.getName() %></td>
   </tr>
   <tr>
    <td>寄送地址</td>
    <td><%= customer.getAddress() %></td>
   </tr>
   <tr>
    <td colspan="2">付款信息</td>
   </tr>
   <tr>
    <td>信用卡类型</td>
    <td><%= customer.getCardType() %></td>
   </tr>
   <tr>
    <td>卡号</td>
    <td><%= customer.getCard()%></td>
   </tr>
   <tr>
    <td>订货项目</td>
    <td>
     <%
      System.out.println("dd");
      String[] books = (String[])session.getAttribute("books");
      for(String book : books){
       
     %>
      <%= book %><br>
     <% 
      }
     %>
    </td>
   </tr>
  </table>
</body>

封装的 Customer类

public class Customer {
 private String name;
 private String address;
 private String cardType;
 private String card;
 public String getName() {
  return name;
 }
 public void setName(String name) {
  this.name = name;
 }
 public String getAddress() {
  return address;
 }
 public void setAddress(String address) {
  this.address = address;
 }
 public String getCardType() {
  return cardType;
 }
 public void setCardType(String cardType) {
  this.cardType = cardType;
 }
 public String getCard() {
  return card;
 }
 public void setCard(String card) {
  this.card = card;
 }
 public Customer(String name, String address, String cardType, String card) {
  super();
  this.name = name;
  this.address = address;
  this.cardType = cardType;
  this.card = card;
 }
 public Customer() {
 }
 
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值