1. 程式人生 > >JavaWeb——使用會話維持狀態2

JavaWeb——使用會話維持狀態2

-c web-inf div resp 返回 ack trac prot 購物車

  在這次的例子裏面,將完成一類似購物車的功能,在客戶訪問網站的時候,會選中自己將要購買的商品,而購物車將始終維持著商品的狀態,會話將聯系起選擇第一個商品(第一個請求),選擇其他商品(其他請求)以及付款等等操作。

1、在Web.xml中配置會話

  <session-config>
    <session-timeout>30</session-timeout>
    <cookie-config>
      <http-only>true</http-only>
    </cookie-config>
    <
tracking-mode>COOKIE</tracking-mode> </session-config>

  使用這樣的設置,會話超過30分鐘將會失效,使用cookie進行會話追蹤,在會話cookie從將HttpOnly置為true用於解決安全問題。

2、頁面邏輯

  這個demo只有兩個網頁,以下是這兩個網頁預覽:

  • 第一頁商品列表頁面將擁有一個點擊進入購物車的鏈接View Cart,和一個商品列表,商品的名字可點擊,點擊之後將把該商品加入購物車。

技術分享圖片

  • 這是購物車頁面的預覽,這裏將有一個返回商品列表頁面的鏈接,然後是一個點擊之後清空購物車的Empty Cart,再然後就是顯示購物車中商品及其數目的列表。

技術分享圖片

3、JSP

  • 先是商品列表頁面,View Cart被點擊之後,action將被置於viewCart這個變量將在doGet方法中使用,這裏使用了一個map記錄了商品的編號和名字,點擊後action將被置於addToCart,productId將賦值為商品的id
<%@ page import="java.util.Map" %>
<!DOCTYPE html>
<html>
    <head>
        <title>Product List</title>
    </head>
    <
body> <h2>Product List</h2> <a href="<c:url value="/shop?action=viewCart" />">View Cart</a><br /><br /> <% @SuppressWarnings("unchecked") Map<Integer, String> products = (Map<Integer, String>)request.getAttribute("products"); for(int id : products.keySet()) { %><a href="<c:url value="/shop"> <c:param name="action" value="addToCart" /> <c:param name="productId" value="<%= Integer.toString(id) %>"/> </c:url>"><%= products.get(id) %></a><br /> <% } %> </body> </html>
  • 這是購物車頁面的JSP,這裏使用的有兩個map,products是記錄商品的id和名字,cart記錄商品的id和已選數,然後是兩個鏈接,第一個鏈接將直接返回商品鏈表頁面,第二個將清空購物車,具體實現是將action賦值為emptyCart,然後交由Servlet操作。
<%@ page import="java.util.Map" %>
<!DOCTYPE html>
<html>
    <head>
        <title>View Cart</title>
    </head>
    <body>
        <h2>View Cart</h2>
        <a href="<c:url value="/shop" />">Product List</a><br /><br />
        <a href="<c:url value="/shop?action=emptyCart" />">Empty Cart</a><br /><br />
        <%
            @SuppressWarnings("unchecked")
            Map<Integer, String> products =
                    (Map<Integer, String>)request.getAttribute("products");
            @SuppressWarnings("unchecked")
            Map<Integer, Integer> cart =
                    (Map<Integer, Integer>)session.getAttribute("cart");

            if(cart == null || cart.size() == 0)
                out.println("Your cart is empty.");
            else
            {
                for(int id : cart.keySet())
                {
                    out.println("   "+products.get(id) + " (qty: " + cart.get(id) +
                            ")<br />");
                }
            }
        %>
    </body>
</html>

4、代碼邏輯

  • 首先是doGet,根據actiond的值將調用不同的方法
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        String action = req.getParameter("action");
        if(action == null){
            action = "browse";
        }

        switch (action){
            case "addToCart":
                //將商品加入購物車中
                this.addToCart(req,resp);
                break;
            case "viewCart":
                //進入購物車頁面
                this.viewCart(req,resp);
                break;
            case "emptyCart":
                //清空購物車
                this.emptyCart(req,resp);
                break;
            case "browse":
            default:
                //進入商品列表頁面
                this.browse(req,resp);
                break;
        }
    }
  • 這兩個方法將直接把請求轉發給JSP並傳遞products這個map對象,
    private void viewCart(HttpServletRequest req, HttpServletResponse resp)
            throws ServletException,IOException {
        req.setAttribute("products",this.products);
        req.getRequestDispatcher("/WEB-INF/jsp/view/viewCart.jsp")
                .forward(req,resp);
    }

    private void browse(HttpServletRequest req, HttpServletResponse resp)
            throws ServletException,IOException {
        req.setAttribute("products",this.products);
        req.getRequestDispatcher("/WEB-INF/jsp/view/browse.jsp")
                .forward(req,resp);
    }
  • addToCart方法將把請求中的商品加入購物車中,首先從請求頭中獲取到商品的id,然後調用HttpServletRequest的getSession方法獲取會話,getSession有兩種方式:getSession()和getSession(boolean)。也就是說其實可以選擇不輸入參數和輸入true或者false三種,其中getSession()和getSession(true)效果是一樣的,如果會話存在就返回已有會話,如果會話不存在就創建一個新的會話(並不會返回null),而getSession(false)如果會話存在就返回會話,如果不存在就返回null。然後查詢會話中的cart特性,如果不存在就添加cart特性,cart其實一個根據id存儲商品數目的map,如果cart中沒有該商品數目最終就置1,如果有將加1。
    private void addToCart(HttpServletRequest req, HttpServletResponse resp)
            throws ServletException,IOException {
        int productId;
        try {
            productId = Integer.parseInt(req.getParameter("productId"));
        }catch (Exception e){
            resp.sendRedirect("shop");
            return;
        }

        HttpSession session = req.getSession();
        if(session.getAttribute("cart") == null){
            session.setAttribute("cart", new Hashtable<Integer, String>());
        }

        Map<Integer, Integer> cart = (Map<Integer, Integer>)session.getAttribute("cart");
        if(!cart.containsKey(productId)){
            cart.put(productId,0);
        }
        cart.put(productId,cart.get(productId) + 1);

        resp.sendRedirect("shop");
    }
  • 最後是清空購物車的emptyCart方法,這裏將刪除會話中的cart,從而實現清空購物車的功能
    private void emptyCart(HttpServletRequest req, HttpServletResponse resp)
            throws ServletException,IOException {
        req.getSession().removeAttribute("cart");
        resp.sendRedirect("shop?action=viewCart");
    }

JavaWeb——使用會話維持狀態2