基于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的简易购物车引发的问题的主要内容,如果未能解决你的问题,请参考以下文章