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

Posted 阳台煮酒

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了基于session的简易购物车引发的问题相关的知识,希望对你有一定的参考价值。

一.功能描述

 页面如下所示:

 

 

运行报错:

 

java.io.FileNotFoundException: E:\\apache-tomcat-8.0.37\\work\\Catalina\\localhost\\20161013ShoppingCart\\SESSIONS.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.37\\work\\Catalina\\localhost\\20161013ShoppingCart\\org\\apache\\jsp\\confirm_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>

 

 

以上是关于基于session的简易购物车引发的问题的主要内容,如果未能解决你的问题,请参考以下文章

ASP.NET购物车问题

JAVA EE中如何使用session实现购物车的功能?

Session机制二(案例)

session management会话管理的原理

为啥代码片段在 matplotlib 2.0.2 上运行良好,但在 matplotlib 2.1.0 上引发错误

Python 练习题_简易购物车