• 基于session的简易购物车引发的问题


    一.功能描述

     页面如下所示:

     

    运行报错:

    java.io.FileNotFoundException: E:apache-tomcat-8.0.37workCatalinalocalhost20161013ShoppingCartSESSIONS.ser (系统找不到指定的路径。)
    at java.io.FileOutputStream.open0(Native Method)
    at java.io.FileOutputStream.open(FileOutputStream.java:270)
    at java.io.FileOutputStream.<init>(FileOutputStream.java:213)
    at java.io.FileOutputStream.<init>(FileOutputStream.java:101)
    at org.apache.catalina.session.StandardManager.doUnload(StandardManager.java:299)
    at org.apache.catalina.session.StandardManager.unload(StandardManager.java:265)
    at org.apache.catalina.session.StandardManager.stopInternal(StandardManager.java:384)
    at org.apache.catalina.util.LifecycleBase.stop(LifecycleBase.java:221)
    at org.apache.catalina.core.StandardContext.stopInternal(StandardContext.java:5533)
    at org.apache.catalina.util.LifecycleBase.stop(LifecycleBase.java:221)
    at org.apache.catalina.core.ContainerBase.removeChild(ContainerBase.java:821)
    at org.apache.catalina.startup.HostConfig.undeploy(HostConfig.java:1395)
    at org.apache.catalina.startup.HostConfig.checkResources(HostConfig.java:1321)
    at org.apache.catalina.startup.HostConfig.check(HostConfig.java:1581)
    at org.apache.catalina.startup.HostConfig.lifecycleEvent(HostConfig.java:284)
    at org.apache.catalina.util.LifecycleSupport.fireLifecycleEvent(LifecycleSupport.java:95)
    at org.apache.catalina.util.LifecycleBase.fireLifecycleEvent(LifecycleBase.java:90)
    at org.apache.catalina.core.ContainerBase.backgroundProcess(ContainerBase.java:1140)
    at org.apache.catalina.core.ContainerBase$ContainerBackgroundProcessor.processChildren(ContainerBase.java:1376)
    at org.apache.catalina.core.ContainerBase$ContainerBackgroundProcessor.processChildren(ContainerBase.java:1380at org.apache.catalina.core.ContainerBase$ContainerBackgroundProcessor.run(ContainerBase.java:1348)

    at java.lang.Thread.run(Thread.java:745)

    定位到问题,发现是confirm无法获取到books属性导致如下代码空指针异常。

    二.问题如下:

    1.进入不了confirm.jsp页面:是因为打开了E:apache-tomcat-8.0.37workCatalinalocalhost20161013ShoppingCartorgapachejspconfirm_jsp.java文件。

      涉及知识点:

    Web容器处理JSP文件请求的执行过程主要包括以下4个部分: 
    1. 客户端发出Request请求
    2. JSP Container 将JSP转译成Servlet的源代码
    3. 将产生的Servlet源代码经过编译后,并加载到内存执行
    4. 把结果Response(响应)至客户端

    很多人都会认为JSP的执行性能会和Servlet相差很多,其实执行性能上的差别只在第一次的执行。因为JSP在执行第一次后,会被编译成Servlet的类文件,即.class,当再重复调用执行时,就直接执行第一次所产生的Servlet,而不再重新把JSP编译成Servelt。因此,除了第一次的编译会花较久的时间之外,之后JSP和Servlet的执行速度就几乎相同了。

    在执行JSP网页时,通常可以分为两个时期:转译时期(Translation Time)和请求时期(Request Time)

    转译时期:JSP网页转移成Servlet类。
    请求时期:Servlet类执行后,响应结果至客户端。

    转译期间做了两件事情:
    转译时期:将JSP网页转移为Servlet源代码 .java.
    编译时期:将Servlet 源代码 .java编译成 Servlet类 .class.

    当JSP网页在执行时,JSP Container 会做检查工作,如果发现JSP网页有更新修改时,JSP Container 才会再次编译JSP成Servlet; 如果JSP没有更新时,就直接执行前面所产生的Servlet.

    根据以上知识可知,我错误的原因在于:
    当JSP网页有更新修改时,confirm_jsp.java文件处于打开状态即confirm_jsp.java文件无法被改动,此时JSP Container 无法将JSP再次编译成 Servlet(无法更新confirm_jsp.java文件),因而运行confirm_jsp.class时不是最新的类,无法打开jsp页面。

      参考:http://zhidao.baidu.com/link?url=nr6hYXlgwXdGzGtj28ivQXhFp1YdKGsGbjBickkipI3cIoQ2kLO8BnYAWRJvz7zJsoo61HMdyOU-yyqfATsG-m1LaT0siFhXgwUJ9PMRT_m

    2.每个页面的sessionID不一样(session丢失问题):是因为在IE浏览器里我禁用了cookie。

      2.1疑惑:IE里浏览器的设置会影响到Eclipse的里的浏览器吗?二者有何关联?

      2.2 浏览器和服务器之间如何传递session的?

         

     

      2.3  不同页面之间是如何传递session的?

         只要浏览器不关闭,任意页面的session都是同一个,代表着浏览器和服务器的一次会话。因此不同页面之间可以利用服务器里进行        

         request.getSession().setAttribute(String attr)和JSP页面里进行session.getAttribute(String attr,String attrVal)。

       

      2.4   session丢失问题常见原因:

         推测应该是没有更新http response的头部的set cookie属性,导致session id没有返回给客户端。抓个包包看看服务端在发送重定向响应的时候有没有把session id也放到response的头      部。然后再看看客户端在重定向再请求服务端的时候有没有把session id带上去

         参考:http://blog.csdn.net/LLorJJ999/article/details/4107464

      2.3 session丢失的解决方法:

     

    3.每个页面的sessionID一样,但servlet1里设置request.getSession().setAttriubte(“books”,book)里设置session的books属性,跳转到step2.jsp却无法获取到session的book属性。

    servlet2里request.getSession().setAttriubte(“customer”,customer)里设置session的customer属性,跳转到confirm.jsp页面却可以获取到session的customer属性。这是为什么?同一session为什么不能获取到session的所有属性?

    相关代码如下:

    打印信息如下:(在Servlet1和Servlet2中能获取到session的book属性,但是step1.jsp和step2.jsp不能获取book属性。customer属性都正常)

       原因:在step1.jsp和step2.jsp里我获取session的book属性是错误的!应该是books属性!因为在servlet1里设置session的attribute时是设置的books属性!如此低级的错误,真是对自己无话可说-_-||

    完整代码如下:

    step1.jsp:

     1 <%@ page language="java" contentType="text/html; charset=UTF-8"
     2     pageEncoding="UTF-8"%>
     3 <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
     4 <html>
     5 <head>
     6 <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
     7 <title>Insert title here</title>
     8 </head>
     9 <body>
    10         <h4>Step1:选择要购买的图书:</h4>
    11         
    12         <%
    13            System.out.println("step1.jsp--->sessionID:"+session.getId() ); 
    14            System.out.println("step1.jsp :MaxInactiveInterval"+session.getMaxInactiveInterval() );  
    15         
    16          %>
    17         <br>
    18         
    19         <form action="<%= request.getContextPath()%>/processStep1" method="post">
    20             <table cellpadding="10"  cellspacing="0" border="1">
    21                 <tr>
    22                     <td>书名</td>
    23                     <td>购买</td>               
    24                 </tr>
    25                 <tr>
    26                     <td>Java</td>
    27                     <td><input type="checkbox" name="book" value="java"></td>               
    28                 </tr>               
    29                 <tr>
    30                     <td>Oracle</td>
    31                     <td><input type="checkbox" name="book" value="Oracle"></td>               
    32                 </tr>  
    33                 <tr>
    34                     <td>Struts</td>
    35                     <td><input type="checkbox" name="book" value="Struts"></td>               
    36                 </tr>  
    37                 <tr>
    38                     <td>Spring</td>
    39                     <td><input type="checkbox" name="book" value="Spring"></td>               
    40                 </tr>  
    41                 <tr>
    42                     <td>Hibernate</td>
    43                     <td><input type="checkbox" name="book" value="Hibernate"></td>               
    44                 </tr>  
    45                 <tr>
    46                      <td colspan="2">
    47                          <input type="submit" value="Submit">
    48                      </td>                    
    49                 </tr>
    50             </table>    
    51         </form>
    52 </body>
    53 </html>

    ProcessServlet1.java:

     1 package com.tt.javaweb;
     2 
     3 import java.io.IOException;
     4 import javax.servlet.ServletException;
     5 import javax.servlet.annotation.WebServlet;
     6 import javax.servlet.http.HttpServlet;
     7 import javax.servlet.http.HttpServletRequest;
     8 import javax.servlet.http.HttpServletResponse;
     9 import javax.servlet.http.HttpSession;
    10 
    11 /**
    12  * Servlet implementation class ProcessStep1Servlet
    13  */
    14 
    15 public class ProcessStep1Servlet extends HttpServlet {
    16     private static final long serialVersionUID = 1L;
    17     /**
    18      * @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse response)
    19      */
    20     protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
    21         
    22         //1.获取选中的图书信息:book
    23         String[] books = request.getParameterValues("book");
    24         
    25         //2.把图书信息放入到HttpSession中
    26         HttpSession session = request.getSession();
    27         session.setAttribute("books", books);
    28         
    29         System.out.println("Servlet1--->sessionID:"+session.getId());
    30         
    31         String[] books2=(String[])session.getAttribute("books");
    32         for(String temp:books2){
    33             System.out.println("servlet1,session attribute[[book]:"+temp);
    34         }
    35         
    36         //3.重定向页面到shoppingCart/step2.jsp
    37         System.out.println(request.getContextPath()+"/shoppingCart/step2.jsp");
    38         response.sendRedirect(request.getContextPath()+"/shoppingCart/step2.jsp");
    39 //        request.getRequestDispatcher("/shoppingCart/step2.jsp").forward(request,response);
    40         //f不同页面之间怎样保证相同的sesion
    41     }
    42 
    43 }

    step2.jsp:

     1 <%@ page language="java" contentType="text/html; charset=UTF-8"
     2     pageEncoding="UTF-8"%>
     3 <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
     4 <html>
     5 <head>
     6 <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
     7 <title>Insert title here</title>
     8 </head>
     9 <body>
    10     
    11     <h4>Step2: 请输入寄送地址和信用卡信息</h4>
    12       <%
    13            System.out.println("step2.jsp--->sessionID:"+session.getId() );        
    14            System.out.println("step2.jsp,session attribute:[book]"+session.getAttribute("books") );   
    15            System.out.println("step2.jsp :MaxInactiveInterval"+session.getMaxInactiveInterval() );  
    16       %>
    17       <br>
    18         
    19     <form action="<%= request.getContextPath() %>/processStep2" method="post">
    20         <table cellpadding="10" cellspacing="0" border="1">
    21         
    22             <tr>
    23                 <td colspan="2">寄送信息</td>
    24             </tr>
    25             
    26             <tr>
    27                 <td>姓名:</td>
    28                 <td><input type="text" name="name"/></td>
    29             </tr>
    30             
    31             <tr>
    32                 <td>寄送地址:</td>
    33                 <td><input type="text" name="address"/></td>
    34             </tr>
    35             
    36             <tr>
    37                 <td colspan="2">信用卡信息</td>
    38             </tr>
    39             
    40         <tr>
    41             <td>种类:</td>
    42             <td>
    43                 <input type="radio" name="cardType" value="Visa"/>Visa
    44                 <input type="radio" name="cardType" value="Master"/>Master
    45             </td>
    46         </tr>
    47         
    48         <tr>
    49             <td>卡号:</td>
    50             <td>
    51                 <input type="text" name="card"/>
    52             </td>
    53         </tr>
    54         
    55         <tr>
    56             <td colspan="2"><input type="submit" value="Submit"/></td>
    57         </tr>
    58             
    59     </table>
    60     </form>
    61     
    62 </body>
    63 </html>

    ProcessServlet2.java:

     1 package com.tt.javaweb;
     2 
     3 import java.io.IOException;
     4 import javax.servlet.ServletException;
     5 import javax.servlet.annotation.WebServlet;
     6 import javax.servlet.http.HttpServlet;
     7 import javax.servlet.http.HttpServletRequest;
     8 import javax.servlet.http.HttpServletResponse;
     9 import javax.servlet.http.HttpSession;
    10 
    11 /**
    12  * Servlet implementation class ProcessStep2Servlet
    13  */
    14 
    15 public class ProcessStep2Servlet extends HttpServlet {
    16     private static final long serialVersionUID = 1L;
    17     protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
    18         // TODO Auto-generated method stub
    19         //1.获取请求参数:name,address,cardType,card
    20         String name = request.getParameter("name");
    21         String address = request.getParameter("address");
    22         String cardType = request.getParameter("cardType");
    23         String card = request.getParameter("card");
    24     
    25         //2.把用户信息封装成一个Customer对象
    26         Customer customer = new Customer(name, address, cardType, card)    ;
    27         
    28         //3.把请求参数存入到HttpSession中          
    29         HttpSession session = request.getSession();
    30         session.setAttribute("customer", customer);
    31         
    32         System.out.println("Servlet2--->sessionID:"+request.getSession().getId());
    33         System.out.println("servlet2,session attribute:[customer]"+session.getAttribute("customer"));
    34         String[] books2=(String[])request.getSession().getAttribute("books");
    35         
    36         for(String temp:books2){
    37             System.out.println("servlet2,session attribute[[book]:"+temp);
    38         }
    39 
    40         //4.重定向页面到confirm.jsp
    41         System.out.println(request.getContextPath()+"/shoppingCart/confirm.jsp");
    42 //        request.getRequestDispatcher("/confirm.jsp").forward(request,response);
    43         response.sendRedirect(request.getContextPath() + "/confirm.jsp");
    44     }
    45 
    46 }

    confirm.jsp:

     1 <%@ page import="com.tt.javaweb.Customer" %>
     2 <%@ page language="java" contentType="text/html; charset=UTF-8"
     3     pageEncoding="UTF-8"%>
     4 <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
     5 <html>
     6 <head>
     7 <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
     8 <title>Insert title here</title>
     9 </head>
    10 <body>
    11        <h4>Step3:订单确认</h4>
    12         <%
    13            System.out.println("confirm.jsp--->sessionID:"+session.getId() );    
    14            System.out.println("confirm.jsp,session attribute:[book]"+session.getAttribute("books") );  
    15            System.out.println("confirm.jsp,session attribute:[customer]"+session.getAttribute("customer") );  
    16            
    17          %>
    18         <br>
    19       <% 
    20        String [] books = (String[])request.getSession().getAttribute("books");
    21        Customer customer = (Customer)request.getSession().getAttribute("customer");
    22     
    23         
    24         //for(String temp:books){
    25         //    System.out.println(temp);
    26         //}
    27     %>
    28     
    29     <table>
    30         <tr>
    31             <td>顾客姓名:</td>
    32             <td><%= customer.getName() %></td>
    33         </tr>
    34         <tr>
    35             <td>地址:</td>
    36             <td><%= customer.getAddress() %></td>
    37         </tr>
    38         <tr>
    39             <td>卡号:</td>
    40             <td><%= customer.getCard() %></td>
    41         </tr>
    42         <tr>
    43             <td>卡的类型:</td>
    44             <td><%= customer.getCardType() %></td>
    45         </tr>
    46         <tr>
    47             <td>Books:</td>
    48             <td>
    49                 <% 
    50                     for(String book: books){
    51                         out.print(book);
    52                         out.print("<br>");
    53                     }
    54                 %>
    55             </td>
    56         </tr>
    57     </table>
    58        
    59 </body>
    60 </html>

     

  • 相关阅读:
    大屏展示功能
    单例模式/原型模式
    .net core ioc
    Log4net
    mvc 过滤器
    webservice
    页面传值 作用域
    Map使用方法
    java获取当前时间撮
    linux 下统计文本行数的各种方法(一)
  • 原文地址:https://www.cnblogs.com/TTTTT/p/5959698.html
Copyright © 2020-2023  润新知