1.通过Servlet来构造一个最简单的购物车,Servlet是JSP的基础,因此利用这个例子来看看Servlet的一些要点。因此,这里做一下限制,只能使用servlet和html。
html代码如下:
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> <meta http-equiv="Pragma" content="no cache"> <meta http-equiv="Cache-control" content="no cache"> <meta http-equiv="Expires" content="0"> <title>Shopping Cart using Servlet</title> </head> <body> <center> <h1>Simple SHOPPING CART</h1> <form method="post" action="SelectionServlet"> <table> <tr> <td><input type="Radio" name="Product" value="apples" checked>Apples</td> </tr> <tr> <td><input type="Radio" name="Product" value="pears" checked>Pears</td> </tr> <tr> <td><input type="Radio" name="Product" value="Checkout" checked>Go to checkout</td> </tr> </table> <br /> <input type="submit" value="submit" /> </form> </center> </body> </html>
要点:
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> <meta http-equiv="Pragma" content="no cache"> <meta http-equiv="Cache-control" content="no cache"> <meta http-equiv="Expires" content="0">
这部分用于控制禁止客户端缓存。
2.SelectionServlet如下
public class SelectionServlet extends HttpServlet { private final float APPLES_PRICE = 1.45F; private final float PEARS_PRICE = 1.75F; public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { String curProd = request.getParameter("Product"); HttpSession cart = request.getSession(); cart.setAttribute("currentProd", curProd); //cart.putValue("currentProd", curProd); if(curProd.equals("Checkout")) response.sendRedirect("CheckoutServlet"); else sendPage(response,curProd); } }
SelectionServlet用于判断用户选择。并将缓存放到session到中。使用的是session.setAttribute()方法。
如果用户行为为checkout,这直接重定向为 CheckoutServlet,否则执行sendPage方法。该方法用于输出一个供用户做进一步选择的界面。
根据MVC的设计原则,Servlet理应只作为控制器,但这里用起做结果输出,使代码显的非常的不可控。
private void sendPage(HttpServletResponse response, String curProd) throws IOException { // TODO Auto-generated method stub response.setContentType("text/html"); PrintWriter out = response.getWriter(); out.println("<html>"); out.println("<head>"); out.println("<title>" + curProd + "</title>"); out.println("</head>"); out.println("<body>"); out.println("<center>"); out.println("<h1>" + curProd + "</h1>"); out.println("<form method='post' action='WeightServlet'"); out.println("<table>"); out.println("<tr>"); out.println(" <td>Quantity required (kg)"); out.println(" <input type='Text' name='Qty'" + " value='' size=5></td>"); out.println("</tr>"); out.println("<tr><td><input type='Radio'" + " name='Option' value='Add' CHECKED>Add to cart.</td></tr>"); out.println("<tr><td><input type='Radio'" + " name='Option' value='Remove'>"); out.println("Remove item from cart.</td></tr>"); out.println("<tr><td><input type='Radio'" + " name='Option' value='Next'>"); out.println("Choose next item.</td></tr>"); out.println("<tr><td><input type='Radio'" + " name='Option' value='Checkout'>"); out.println("Go to checkout.</td></tr>"); out.println("</table>"); out.println("<input type='Submit' value='Submit'>"); out.println("</form>"); out.println("</center>"); out.println("</body>"); out.println("</html>"); out.flush(); }
这里输出了一张表单,并且该表单的action指定的是 WeightServlet。
public class WeightServlet extends HttpServlet { public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { HttpSession cart = request.getSession(); String curProd = (String) cart.getAttribute("currentProd"); String choice = request.getParameter("Option"); if (choice.equals("Next")) response.sendRedirect("ShoppingCart.html"); if (choice.equals("Checkout")) response.sendRedirect("CheckoutServlet"); if (choice.equals("Add")) { doAdd(cart, request); response.sendRedirect("ShoppingCart.html"); } if (choice.equals("Remove")) { doRemove(cart); response.sendRedirect("ShoppingCart.html"); } } }
这里再次进行flow control,根据用户的选择做出不同的响应。更为关键的是,每次做出的选择我们都使用了session进行了跟踪,将其存储在服务器端,当用户再次选择时,不会丢失结果。
与设置session相似的是,得到session的值使用 session.getAttribute()方法。同样,删除session的方法时调用 session.removeAttribute()方法。
doRemove()和doAdd()方法如下:
private void doRemove(HttpSession cart) { String currentProduct = (String) cart.getAttribute("currentProd"); Object product = cart.getAttribute(currentProduct); if (product != null) cart.removeAttribute(currentProduct); } private void doAdd(HttpSession cart, HttpServletRequest request) { String curProd = (String) cart.getAttribute("currentProd"); String qty = request.getParameter("Qty"); if(qty!=null){ if(curProd.equals("apples")) cart.setAttribute("apples", qty); else cart.setAttribute("pears", qty); } }
最后,我们关注最终转发的CheckoutServlet,其用于显示用户的购物列表。
public class CheckoutServlet extends HttpServlet { private final float APPLES_PRICE = 1.45F; private final float PEARS_PRICE = 1.75F; @Override protected void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { HttpSession cart = request.getSession(); response.setContentType("text/html"); PrintWriter out = response.getWriter(); out.println("<html>"); out.println("<head>"); out.println("<title>Checkout</title>"); out.println("</head>"); out.println("<body>"); out.println("<center>"); out.println("<h1>Order List</h1>"); out.println("<table BORDER=2>"); out.println("<tr>"); out.println("<th>Item</th>"); out.println("<th>Weight(kg)</th>"); out.println("<th>Costs</th>"); out.println("</tr>"); cart.removeAttribute("currentProd"); Enumeration<?> prodNames = cart.getAttributeNames(); float totalCost = 0; int numProducts = 0; while (prodNames.hasMoreElements()) { float wt = 0, cost = 0; String product = (String) prodNames.nextElement(); String stringWt = (String) cart.getAttribute(product); wt = Float.parseFloat(stringWt); if (product.equals("apples")) cost = APPLES_PRICE * wt; else if (product.equals("pears")) cost = PEARS_PRICE * wt; out.println("<tr>"); out.println("<td>" + product + "</td>"); out.println("<td>" + wt + "</td>"); out.println("<td>" + cost + "</td>"); out.println("</tr>"); totalCost += cost; numProducts++; } if (numProducts == 0) { out.println("<tr><td>*** No orders placed! ***</td></tr>"); } else { out.println("<tr"); out.println("<td></td>"); // Blank cell. out.println("<td>Total cost:</td>"); out.println("<td>" + totalCost + "</td>"); out.println("</tr>"); } out.println("</table>"); out.println("</center>"); out.println("</body>"); out.println("</html>"); out.flush(); } }
这里的关键是取得session中的多条记录,使用session.getAttributeNames()方法。
不得不说,使用servlet做视图的输出非常的费劲。