📄 l4.html
字号:
type="submit" value="Delete"><BR><input type="hidden" name=
"delindex" value='<%= index %>'><BR><input type="hidden"
name="action"
value="DELETE"><BR></form> <BR></td><BR></tr> <BR><%
} %><BR></table><BR><p><BR><form
name="checkoutForm"<BR>action="/examples/servlet/ShoppingServlet"<BR>method="POST"><BR><input
type="hidden" name="action" value="CHECKOUT"><BR><input
type="submit" name="Checkout"
value="Checkout"><BR></form><BR></center><BR><% }
%><BR><BR><BR>这里,Cart.jsp按照MVC的模式1处理基于SESSION的购物车的表现。请看Cart.jsp开始处的代码:<BR><BR><%<BR>Vector
buylist = (Vector) session.getValue("shopping.shoppingcart");<BR>if
(buylist != null && (buylist.size() > 0))
{<BR>%><BR><BR>本质上,这段代码从SESSION中取出“购物车”。如果“购物车”为空或者没有被创建,它就什么也不显示。所以,在用户第一次访问应用时,其界面如图:<BR><BR><BR>如果“购物车”不为空,用户选择的商品从车中取出,依次显示在页面上:<BR><BR><%<BR>for
(int index=0; index < buylist.size(); index++) {<BR>CD anOrder = (CD)
buylist.elementAt(index);<BR>%><BR><BR>一旦生成一个物品的说明,就使用JSP按照事先设定的模板将其插入静态HTML页面。下图显示了用户选购一些物品后的界面:<BR><BR>(略)<BR><BR>需要注意的一个重要的地方是所有关于Eshop.jsp,Cart.jsp的处理有一个控制SERVLET,ShoppingServlet.java,代码在源程序3中:<BR><BR>Listing
3:<BR>ShoppingServlet.java <BR><BR>import java.util.*;<BR>import
java.io.*;<BR>import javax.servlet.*;<BR>import
javax.servlet.http.*;<BR>import shopping.CD;<BR>public class
ShoppingServlet extends HttpServlet {<BR>public void init(ServletConfig
conf) throws ServletException {<BR>super.init(conf);<BR>}<BR>public void
doPost (HttpServletRequest req, HttpServletResponse res)<BR>throws
ServletException, IOException {<BR>HttpSession session =
req.getSession(false);<BR>if (session == null)
{<BR>res.sendRedirect("http://localhost:8080/error.html");<BR>}<BR>Vector
buylist=<BR>(Vector)session.getValue("shopping.shoppingcart");<BR>String
action = req.getParameter("action");<BR>if (!action.equals("CHECKOUT"))
{<BR>if (action.equals("DELETE")) {<BR>String del =
req.getParameter("delindex");<BR>int d = (new
Integer(del)).intValue();<BR>buylist.removeElementAt(d);<BR>} else if
(action.equals("ADD")) {<BR>//any previous buys of same cd?<BR>boolean
match=false;<BR>CD aCD = getCD(req);<BR>if (buylist==null) {<BR>//add
first cd to the cart<BR>buylist = new Vector(); //first
order<BR>buylist.addElement(aCD);<BR>} else { // not first buy<BR>for (int
i=0; i< buylist.size(); i++) {<BR>CD cd = (CD)
buylist.elementAt(i);<BR>if (cd.getAlbum().equals(aCD.getAlbum()))
{<BR>cd.setQuantity(cd.getQuantity()+aCD.getQuantity());<BR>buylist.setElementAt(cd,i);<BR>match
= true;<BR>} //end of if name matches<BR>} // end of for<BR>if
(!match) <BR>buylist.addElement(aCD);<BR>}<BR>}<BR>session.putValue("shopping.shoppingcart",
buylist);<BR>String url="/jsp/shopping/EShop.jsp";<BR>ServletContext sc =
getServletContext();<BR>RequestDispatcher rd =
sc.getRequestDispatcher(url);<BR>rd.forward(req, res);<BR>} else if
(action.equals("CHECKOUT")) {<BR>float total =0;<BR>for (int i=0; i<
buylist.size();i++) {<BR>CD anOrder = (CD) buylist.elementAt(i);<BR>float
price= anOrder.getPrice();<BR>int qty = anOrder.getQuantity();<BR>total +=
(price * qty);<BR>}<BR>total += 0.005;<BR>String amount = new
Float(total).toString();<BR>int n = amount.indexOf('.');<BR>amount =
amount.substring(0,n+3);<BR>req.setAttribute("amount",amount);<BR>String
url="/jsp/shopping/Checkout.jsp";<BR>ServletContext sc =
getServletContext();<BR>RequestDispatcher rd =
sc.getRequestDispatcher(url);<BR>rd.forward(req,res);<BR>}<BR>}<BR>private
CD getCD(HttpServletRequest req) {<BR>//imagine if all this was in a
scriptlet...ugly, eh?<BR>String myCd = req.getParameter("CD");<BR>String
qty = req.getParameter("qty");<BR>StringTokenizer t = new
StringTokenizer(myCd,"/");<BR>String album= t.nextToken();<BR>String
artist = t.nextToken();<BR>String country = t.nextToken();<BR>String price
= t.nextToken();<BR>price = price.replace('$',' ').trim();<BR>CD cd = new
CD();<BR>cd.setAlbum(album);<BR>cd.setArtist(artist);<BR>cd.setCountry(country);<BR>cd.setPrice((new
Float(price)).floatValue());<BR>cd.setQuantity((new
Integer(qty)).intValue());<BR>return
cd;<BR>}<BR>}<BR><BR><BR>每次用户用Eshop.jsp增加一个商品,页面就请求控制SERVLET。控制SERVLET决定进一步的行动,并处理增加的商品。接着,控制SERVLET实例化一个新的BEAN
CD代表选定的商品,并在返回SESSION前更新购物车对象。<BR><BR>Listing
4:<BR>CD.java <BR><BR>package shopping;<BR>public class CD
{<BR>String album;<BR>String artist;<BR>String country;<BR>float
price;<BR>int quantity;<BR>public CD()
{<BR>album="";<BR>artist="";<BR>country="";<BR>price=0;<BR>quantity=0;<BR>}<BR>public
void setAlbum(String title) {<BR>album=title;<BR>}<BR>public String
getAlbum() {<BR>return album;<BR>}<BR>public void setArtist(String group)
{<BR>artist=group;<BR>}<BR>public String getArtist() {<BR>return
artist;<BR>}<BR>public void setCountry(String cty)
{<BR>country=cty;<BR>}<BR>public String getCountry() {<BR>return
country;<BR>}<BR>public void setPrice(float p)
{<BR>price=p;<BR>}<BR>public float getPrice() {<BR>return
price;<BR>}<BR>public void setQuantity(int q)
{<BR>quantity=q;<BR>}<BR>public int getQuantity() {<BR>return
quantity;<BR>}<BR>}<BR><BR><BR>注意,我们的SERVLET中具有附加的智能,如果一个物品被重复选择,不会增加新的记录,而是在以前的记录上更新计数。控制SERVLET也响应Cart.jsp中的行为,如修改数量,删除商品,还有结帐。如果结帐,控制通过下述语句转向Checkout.jsp页面(源程序5):<BR><BR>String
url="/jsp/shopping/Checkout.jsp";<BR>ServletContext sc =
getServletContext();<BR>RequestDispatcher rd =
sc.getRequestDispatcher(url);<BR>rd.forward(req,res);<BR><BR>Listing
5:<BR>Checkout.jsp <BR><BR><%@ page session="true"
import="java.util.*, shopping.CD"
%><BR><html><BR><head><BR><title>Music Without
Borders Checkout</title><BR></head><BR><body
bgcolor="#33CCFF"><BR><font face="Times New Roman,Times"
size=+3><BR>Music Without Borders
Checkout<BR></font><BR><hr><p><BR><center><BR><table
border="0" cellpadding="0" width="100%"
bgcolor="#FFFFFF"><BR><tr><BR><td><b>ALBUM</b></td><BR><td><b>ARTIST</b></td><BR><td><b>COUNTRY</b></td><BR><td><b>PRICE</b></td><BR><td><b>QUANTITY</b></td><BR><td></td><BR></tr><BR><%<BR>Vector
buylist = (Vector) session.getValue("shopping.shoppingcart");<BR>String
amount = (String) request.getAttribute("amount");<BR>for (int i=0; i <
buylist.size();i++) {<BR>CD anOrder = (CD)
buylist.elementAt(i);<BR>%><BR><tr><BR><td><b><%=
anOrder.getAlbum() %></b></td><BR><td><b><%=
anOrder.getArtist()
%></b></td><BR><td><b><%=
anOrder.getCountry()
%></b></td><BR><td><b><%= anOrder.getPrice()
%></b></td><BR><td><b><%=
anOrder.getQuantity()
%></b></td><BR></tr><BR><%<BR>}<BR>session.invalidate();<BR>%><BR><tr><BR><td>
</td><BR><td>
</td><BR><td><b>TOTAL</b></td><BR><td><b>$<%=
amount %></b></td><BR><td>
</td><BR></tr><BR></table><BR><p><BR><a
href="/examples/jsp/shopping/EShop.jsp">Shop some
more!</a><BR></center><BR></body><BR></html><BR><BR><BR>结帐页面简单地从SESSION中取出购物车,然后显示每个物品和总金额。这里的关键是要结束SESSION,因此在页面中有一个session.invalidate()调用。这一处理有两个原因。首先,如果不结束SESSION,用户的购物车不会被初始化,如果用户要继续购买,车中会保留他已经支付过的商品。另外,如果用户不结帐就离开了,则SESSION会继续占用有效的资源直到过期。过期时间一般是30分钟,在一个大的站点上,这样的情况会很快导致资源耗尽。当然,这是我们不愿看到的。<BR><BR><BR>注意,所有的资源分配在这个例子中是基于SESSION的。所以,你必须确保控制SERVLET不被用户访问,即使是意外的访问也不允许。这可以在控制检查到一个非法访问时用一个简单的重定向错误页面来处理。见源代码6。<BR><BR>Listing
6:<BR>error.html <BR><BR><html><BR><body><BR><h1><BR>Sorry,
there was an unrecoverable error! <BR><BR>Please try <a
href="/examples/jsp/shopping/EShop.jsp">again</a>.<BR></h1><BR></body><BR></html><BR><BR><BR><FONT
color=#ff0000>小结<BR></FONT><BR>本章的讨论显示,使用模式2,JSP和SERVLET可以在功能上最大限度的分开。正确地使用模式2,导致一个中心化的控制SERVLET,以及只完成显示的JSP页面。另一方面,模式2的实现很复杂。因此,在简单的应用中,可以考虑使用模式1。<BR><BR></P>
</td>
</tr>
</td>
</tr>
</div>
</body>
</html>
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -