朕JAVEE 实验04 实验报告

  • 项目描述

项目名字

所用知识点

项目效果

Lab 12

会话管理与数据传递

①能使用过滤器将所有Sevlet统一编码

②Cookie专题:能通过Cookie传递样式表信息,能输出Cookie的一些属性和方法

③hidden专题:能添加客户,编辑用户,显示用户列表

④session专题:将老师程序解耦为product和cart两个Servlet交互。通过txt文件读入产品信息,添加店铺和库存信息,若商品售光则不予显示。购物车能合并相同商品的不同订单,购物车按照店铺>产品分组显示。将不合理的订单或其他错误信息显示给客户。更正了原项目刷新导致表单重复提交的错误。

⑤url专题:添加了城市“云南”。点击城市能分页显示其十个特色景点。

Lab 13

JSP、Servlet、EL表达式的应用

用相应知识点展示了一个小故事。

Lab 14

JSP、JSTL、EL表达式的示例应用

①用两种URL快捷登录

②设置、传递、展示了Cookie信息

③一些服务器信息的展示、不同域变量的设置和展示

④模拟超市,进行页面信息的交互

Lab 15

javaBean作用域

①做了javaBean使用域分别为page、request、session、application的登录页面

②page:无论登录几次,都是第一次登录

③request:通过include到success页面,显示出类通过requst共享。即一次登录,会因为success页面,而变成两次登录

④session:登录几次就是几次,关掉浏览器会失去信息

⑤application:即使关掉浏览器,再打开,其登录次数的数据不会丢失

 

  • 问题描述

问题1描述:在刷新Product页时,发现浏览器果然重复了加入购物车操作,即重复提交表单。如图:

问题分析:肯定是购买数据在使用后未清零。但是后续发现由于是getParameter,并不能进行变量的修改。

问题解决:将购买订单增添一个独一无二的timeId,将上一个时间timeId储存在session中,如果发现订单与session的timeId相同,则判断为重复提交表单,不予处理。

 

问题3描述:如图:

问题分析:代码没写完整。

问题解决:补全代码。(虽然问题很一般,但这个警告很独特,留作纪念。)

 

问题4描述:严重: Servlet.service() for servlet [ShoppingProductServlet] threw exception

java.lang.StackOverflowError

at org.apache.catalina.core.ApplicationHttpRequest.setAttribute(ApplicationHttpRequest.java:306)

at org.apache.catalina.core.ApplicationHttpRequest.setAttribute(ApplicationHttpRequest.java:306)

at org.apache.catalina.core.ApplicationHttpRequest.setAttribute(ApplicationHttpRequest.java:306)

问题分析:由于.StackOverflowError,可能是两个Servlet的相互调用陷入死循环。

问题解决:分析逻辑,解开死循环。

 

问题5描述:java.lang.IllegalStateException: Cannot forward after response has been committed

at org.apache.catalina.core.ApplicationDispatcher.doForward(ApplicationDispatcher.java:323)

at org.apache.catalina.core.ApplicationDispatcher.forward(ApplicationDispatcher.java:312)

问题分析:是txt路径问题。

问题解决:百度,寻找到txt合适的存放路径,并且合理取出。

 

  • 知识点总结

【1】@Override

       答:@Override是伪代码,表示重写。(当然不写@Override也可以),不过写上有如下好处: 1、可以当注释用,方便阅读;2、编译器可以给你验证@Override下面的方法名是否是你父类中所有的,如果没有则报错。例如,你如果没写@Override,而你下面的方法名又写错了,这时你的编译器是可以编译通过的,因为编译器以为这个方法是你的子类中自己增加的方法。

 

【2】Cookie MaxAge属性及其使用

       答:public void setMaxAge(int expiry); maxAge 可以为正数,表示此cookie从创建到过期所能存在的时间,以秒为单位,此cookie会存储到客户端电脑,以cookie文件形式保存,不论关闭浏览器或关闭电脑,直到时间到才会过期。可以为负数,表示此cookie只是存储在浏览器内存里,只要关闭浏览器,此cookie就会消失。maxAge默认值为-1。

还可以为0,表示从客户端电脑或浏览器内存中删除此cookie。

 

【3】eclipse写JAVA相对路径的总结

答:使用工程相对路径是靠不住的。使用CLASSPATH路径是可靠的。对于程序要读取的文件,尽可能放到CLASSPATH下,这样就能保证在开发和发布时候均正常读取

在Java开发工具的project中使用相对路径

在project中,相对路径的根目录是project的根文件夹(与src平级)了。

创建文件的写法是:

File f = new File("src/xxx/a.txt");

File f = new File("xxx/b.txt");

注意:路径不以“/”开头;

 

通过CLASSPATH读取包内文件

读取包内文件,使用的路径一定是相对的classpath路径,比如a,位于包内,此时可以创建读取a的字节流:

InputStream in = ReadFile.class.getResourceAsStream("/com/lavasoft/res/a.txt");

注意:这里必须以“/”开头

获取CLASSPATH下文件的绝对路径

当使用相对路径写入文件时候,就需要用到CLASSPATH绝对路径(Eclipse中是bin目录)

 

  • 思考题

【1】servletDataPass.url

① 请选一个自己感兴趣的城市,列举十个地点,加入到页面中

答:项目效果如图。

 

② 体会和理解用request和response通过页面传值的情况

request.getRequestDispatcher("a.jsp").forward(rquest,response)只能转到同一个Web应用程序中的某个资源;可以共享request中的数据;地址不变化。

response.sendRedirect("b.jsp")可以重定向到任何URL;数据不共享;地址栏也会变化。

response.setHeader("REFRESH", stayTime+";URL="+URL)重定向有延迟时间。

Request页面传值可以通过使用requst域中的变量、信息,进行传值。使用request.setAttribute()、request.getParameter()等。

Response页面传值可以将参数写在URL上,如url+”?变量名=变量值”+“&”+”另一个变量名=变量值”。

 

③ 思考,用Servlet的方式,页面间传递了哪些数据?以什么样的形式传递数据的?数据的封装形式是什么?

答:页面间传递了city、page数据。传递数据的行为封装成URL,数据在URL中以相应格式的字符串存储。以URL形式传递。取出数据的行为封装为request.getParameter函数。

 

【2】servletDataPass.hidden

① 包中有多少次处理中文乱码的地方?

       答:4次。CustomerServlet的sendCustomerList、sendEditCustomerForm、doGet、doPost。

 

② 能不能将这些处理封装在一个过滤器中来完成?

       答:能。依旧删掉Servlet相关编码信息,使用过滤器编码格式,在xml中,此过滤器的url-pattern为/*,他能为项目内所有Servlet设置编码。

 

③ 自行添加过滤器,完成全包统一编码,处理中文乱码问题

       答:见项目。

 

④ 自行添加一个客户的信息

       答:项目效果如图。

 

⑤ 隐藏域在哪里?在传递数据时,它是怎么发挥作用的?

       答:隐藏域的代码格式为:<input type="hidden" name="..." value="...">其中,type="hidden"定义隐藏域,name属性定义隐藏域的名称,要保证数据的准确采集,必须定义一个独一无二的名称,value属性定义隐藏域的值。

隐藏域是用来收集或发送信息的不可见元素,对于网页的访问者来说,隐藏域是看不见的。当表单被提交时,隐藏域就会将信息用你设置时定义的名称和值发送到服务器上。

 

[3] servletDataPass.cookie

① Cookie在哪里设置的,在哪里用的?

       答:此项目中,Cookie在PreferenceServlet里设置。CookieClassServlet通过获取Cookie中的"maxRecords"值,调节展示的Cookie方法名的数目。CookieInfoServlet通过获取Cookie中的值,进行样式修改。

 

② 在浏览器中,怎么查看Cookie?

       答:程序员可以通过写代码查看,如项目中,先使用“request.getCookies()”获取Cookie对象,再遍历其中的信息,再进行打印输出。

而针对直接查看浏览器的Cookie,不同浏览器有不同的方法。如ie浏览器,可按F12进入浏览器的开发者模式——console——在命令行输入javascript:alert(document.cookie),再回车。Chrome浏览器,点击url左边的文本图标, 单击cookie。如图。

 

③ 自行添加过滤器,完成全包统一编码,处理中文乱码问题

       答:建立过滤器,在其中进行编码设置,并且将请求转发给过滤器链上下一个对象。应当注意的是在xml配置中,此过滤器的url-pattern为/*。

 

④ Cookie中有哪些方法,一般可用于做什么?

void  setMaxAge(int expiry)

设置cookie的有效期,以秒为单位

String getMaxAge()

获取cookie的有效期,以秒为单位

void  setValue(Stringh newValue)

在cookie创建后,对cookie进行赋值

String getName()

获取cookie的名

String getValue()

获取cookie的值

 

⑤ 导航菜单是怎么产生的,如何发挥作用的?

       答:Servlet写页面时,都使用了“PreferenceServlet.MENU “,而我们追溯MENU,发现它是PreferenceServlet中的String全局变量,采用的html格式,具体内容为导航菜单。在各Servlet中,在写页面时,在合适处直接插入PreferenceServlet.MENU,便可以得到导航菜单。

 

⑥ 样式表是怎么产生的,如何发挥作用的?

       答:样式表是通过设置html中相应style格式的字符串内容,再在Servlet写页面时,在合适处插入此字符串内容,页面以html直接编译为具体含义,由此获得样式表,并发挥样式表作用。

 

⑦ 样式中的字色是如何控制的?

       答:首先有默认字色,其次如果在PreferenceServlet中修改了“字色“表格的值,则在点击“设置Set”时,Servlet会调用doPost()方法,并在其中获取表格信息,加入Cookie中。而页面的字色在显示前,会从Cookie中获取相应值,再进行显示。

 

【4】servletDataPass.session

① JavaBean在哪里,有几个Bean,在这个Bean中有哪些项?有没有无参构造函数?

       答:servletDataPass.session包内的Product.java、ShoppingItem.java,共两个。没用无参构造函数。

 

② 购物车在哪里?有哪些具体的功能?

       答:购物车在

 

③ 观察它的web.xml中的描述符,根据url-pattern可知,这一个Servlet完成哪些功能?

答:/products展示所有商品,/viewProductDetails获悉个体商品的详细信息,/addToCart添加商品进购物车,/viewCart查看购物车。

 

④ 如果把上述功能分散到不同的Servlet中,应该如何进行解耦?

       答:展示商品、获悉商品详情可以在一个Servlet,加商品进购物车、查看购物车应该是另一个Servlet。

 

⑤ 如果产品数据不在初始化时创建,在文件中如何读取呢,可不可以做成可以自由管理的产品?

答:可以做成。只需要将文件信息先读出来,再自由管理,再将产品数据、购物车数据导出成文件。

 

⑥ 为何产品列表不需要request,而产品详情需要request对象?购物车也需要request对象吗?

       答:因为在老师项目中,产品信息是在类初始化的时候直接存在类变量中,可以直接For循环打印。但是产品详情是针对用户点击的产品,浏览器将与用户交互的信息存在request中。需要,因为购物车添加的商品及其数量也是从浏览器与用户的交互信息中取出。

 

⑦ 如果让你处理那些未处理的异常,你有什么思路?你可能怎么给出用户提示?

       答:首先try..catch捕获异常,标记到日志,然后进行页面上的相应反馈。如产品购买数量大于产品库存,则如天猫、淘宝一般,在购物车处显示错误。

 

⑧ 查看产品详情时,id号是何传进行数据传递的?用的是什么技术?

       答:项目中,id是通过表单传递的,使用了隐藏域。详情见【2】servletDataPass.hidden⑤隐藏域处。

 

⑨ session在哪里,它的作用是什么?怎么产生的,在哪里用的?

       答:浏览器第一次访问服务器会在服务器端生成一个session,有一个sessionid和它对应。Tomcat 生成的sessionid叫做jsessionid。

Java中的session

创建

sessionid第一次产生是在直到某server端程序调用 HttpServletRequest.getSession(true)这样的语句时才被创建。

删除

超时;程序调用HttpSession.invalidate();程序关闭。

(Session不会因为浏览器的关闭而删除)

session的id

当客户端第一次请求session对象时候,服务器会为客户端创建一个session,并将通过特殊算法算出一个session的ID,用来标识该session对象。

tomcat的ManagerBase类提供创建sessionid的方法:随机数+时间+jvmid。

 

项目中,session在服务器端程序运行的过程中创建的(这里表现为在第一次进入浏览器)。session在doPost()中,加入商品进购物车时。由request.getSession()调出使用,后统一加入商品。在showCart()中,查看购物车的时候调出使用。主要方法是先从session中获取变量,再变量修改,再将变量修改同步进session。

 

⑩ 多次测试后,你觉得这个购物车有哪些方面需要改进?

  • 产品缺少店铺信息、库存信息。
  • 购物车缺少折扣(满减)等情况
  • 购物车划分等级应该为 店铺>产品
  • 购物车不能进行选择购买
  • 购物车不能对已有的产品进行修改(或与产品信息同步变更)
  • 购物车不能将同样产品进行数目叠加
  • 购物车不能在结账时进行优惠卷、满减
  • 购物车不能在结账之后生成订单
  • 未向用户进行反馈(如购买数量为负数时,只是不操作而已)
  • 在购物车里已有物品时,点击刷新产品Products页,购物车会直接添加上一次选中购买的物品(重大失误)。

 

⑪ 多添加几种产品进来?能做到吗?

       答:能。比如说我通过txt文件传入更多产品数据。

 

⑫ 这个购物车可以清空吗?关闭浏览器再打开或是换一个别的浏览器后,这个购物车还在吗?

       答:购物车已经排除购买负数数量的产品,又不提供删改操作,是不能直接清空购物车的。但我们知道cart是存放在session上的,关闭浏览cart就不在了。

进行关闭浏览器再打开或是换一个别的浏览器操作后,遇到的问题是此网页完全打不开。

⑬ 百度一下,企业级的购物车,应该具有有哪些功能?

  • 已选中商品的金额计算
  • 修改规格
  • 商品数量、价格的自动更新(如商品已下架、已打折)
  • 促销活动显示、优惠券领取
  • 分组(店铺>>活动>>商品)
  • 生成订单

 

  • 心得

项目工期一直在拖延,说星期三做完,结果星期四搭进去了一整天才能做完。这体现我对项目量、自己绕的冤枉路长度的错误评估。另外自己对于文档的太过执着,目前都4000+字了,让自己疲惫不堪,素材却还没写完。很可能项目的生命线被文档拉长了。

很满意自己在写代码前进行了完整的设计,这让我没有继续上次代码重构的冤枉路,但是!这次我踏进了左右手不协调的冤枉路,将form错打成from却不自知。于是在提交表单时完美失误,这样的失误让我将代码逻辑从头到尾判断了一遍,甚至开始绝望。在漫长的debug之后,我甚至想到是不是form的位置不对,也是这个想法,让我发现了单词拼写的失误。甚是同情自己,但也知道自己这一个多小时内对之前知识进行了巩固。希望自己吃一堑长一智。

现在的问题是,我将项目设计很美好,但没有足够的胜负欲迫使自己达到相应设计。项目还是半成品,我就结束了编程。可能以后自己就有胜负欲了吧。

 

仅以纪念2019年第4次javaee实验。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章