• Servlet会话管理三(HttpSession)


    Session是服务器端技术,服务器在运行时可以为每一个用户的浏览器创建一个其独享的HttpSession对象。由于Session为浏览器用户所独享,所以用户在访问服务器的web资源时,可以把各自的数据放在各自的Session对象中,当用户再次访问服务器中的其他web资源时,其他web资源再从Session对象中取出用户的数据。

    Session和Cookie的最大区别是:

    (1)Session是将数据保存在服务器上;而Cookie是将数据以文本的形式保存在客户端浏览器上,由浏览器进行管理的维护。

    (2)Session对象可以存放多个name和多个Object;而一个cookie只能放一个name和一个value

    HttpSession对象在用户第一次访问网站的时候自动被创建,可以通过调用HttpServletRequest的getSession()方法获取该对象。

    HttpSession getSession()  // 返回当前Session对象,如果没有则创建一个并返回。
    HttpSession getSession(boolean create)  // 返回当前Session对象,如果没有,当create是true时创建一个并返回,当create时false时返回null

    注意,所有保存在HttpSession对象中的数据不会被发送到客户端,不同于其他会话管理技术,Servlet容器为每个HttpSession生成唯一的标识,并将该标识发送给浏览器,或创建一个名为JSESSIONID的cookie,或在URL后附加一个名为jsessionid的参数。在后续的请求中,浏览器回京标识交给服务器,这样服务器就可以识别请求是由哪个用户发起的。Servlet容器会自动选择一种方式来传递标识,无需开发人员介入。

    通过HttpSession的setAttribute(name, value)方法将数据放入Session对象中。可存放多对数据。调用该方法时如果name已经使用过,则新值会覆盖旧值。注意不同于URL重写、表单隐藏域、Cookie技术,放入Session对象中的数据是存储在服务器内存中,因此尽量不要存放太多数据,否则会影响性能。存放在Session对象中的值可以是任意实现了java.io.Serializable接口的java对象,因为Servlet容器必要时会将这些对象放入文件或数据库中。如果对象未实现java.io.Serializable接口,则Servlet容器在序列化的时候会失败并报错。

    void setAttribute(java.lang.String name, java.lang.Object value)

    通过调用HttpSession的getAttribute(name)方法可以获取之前放入的数据

    java.lang.Object getAttribute(java.lang.String name)  // 返回该Session对象中特定名称的数据
    java.util.Enumeration<java.lang.String> getAttributeNames()  // 返回放入该session对象中的所有数据的名字

    可以通过HttpSession的getId()来获取该Session对象的标识

    java.lang.String getId()  // 获取该Session对象的标识

    Seesion的使用原理

    1)浏览器第一次访问服务器,服务器会自动创建Session对象,给Session对象分配一个唯一的ID,JSESSIONID
    2)将JSESSIONID作为cookie的值发送给浏览器保存
    3)浏览器第二次访问服务器时,会将保存有JSESSIONID的cookie随HTTP header发送到服务器
    4)服务器从cookie中得到JSESSIONID,然后在服务器中搜索该JSESSIONID的Session对象。找到则直接返回该对象;找不到则创建新的Session对象。

     Session对象的销毁

    1)调用void invalidate()方法  // 强制该Session对象过期,并清空存储的数据
    2)session对象过期(超时)Tomcat 中 session 的默认有效时间是 30 min
    3)服务器重启 修改修改 session 持久化配置

    修改session默认有效时间

    Tomcat中session的默认有效时间是30min。可以在Tomcat安装目录下的 conf/web.xml 文件中修改。

    session持久化

    session持久化是指当Tomcat重启后,session中仍然含有数据。

    可以在 Tomcat 的安装目录下的 conf/context.xml 进行修改

        <!-- Uncomment this to disable session persistence across Tomcat restarts -->
        <!--
        <Manager pathname="" />
        -->

    改为

        <!-- Uncomment this to disable session persistence across Tomcat restarts -->
        <Manager pathname="" />

    实例

    package app02a.httpsession;
    
    public class Product {
        private int id;
        private String name;
        private String description;
        private float price;
        
        public Product(int id, String name, String description, float price) {
            this.id = id;
            this.name = name;
            this.description = description;
            this.price = price;
        }
        
        public int getId() {
            return id;
        }
        public void setId(int id) {
            this.id = id;
        }
        public String getName() {
            return name;
        }
        public void setName(String name) {
            this.name = name;
        }
        public String getDescription() {
            return description;
        }
        public void setDescription(String description) {
            this.description = description;
        }
        public float getPrice() {
            return price;
        }
        public void setPrice(float price) {
            this.price = price;
        }
    }
    package app02a.httpsession;
    
    public class ShoppingItem {
        private Product product;
        private int quantity;
        
        public ShoppingItem(Product product, int quantity) {
            this.product = product;
            this.quantity = quantity;
        }
        
        public Product getProduct() {
            return this.product;
        }
        public void setProduct(Product product) {
            this.product = product;
        }
        public int getQuantity() {
            return this.quantity;
        }
        public void setQuantiry(int quantity) {
            this.quantity = quantity;
        }
    }
    package app02a.httpsession;
    
    import java.io.IOException;
    import java.io.PrintWriter;
    import java.text.NumberFormat;
    import java.util.ArrayList;
    import java.util.List;
    import java.util.Locale;
    
    import javax.servlet.ServletException;
    import javax.servlet.annotation.WebServlet;
    import javax.servlet.http.HttpServlet;
    import javax.servlet.http.HttpServletRequest;
    import javax.servlet.http.HttpServletResponse;
    import javax.servlet.http.HttpSession;
    
    @WebServlet(name = "ShoppingCartServlet", urlPatterns = { "/products", "/viewProductDetails", "/addToCart", "/viewCart" })
    public class ShoppingCartServlet extends HttpServlet {
        private static final long serialVersionUID = 1L;
        private static final String CART_ATTRIBUTE = "cart";
        
        private List<Product> products = new ArrayList<Product>();
        private NumberFormat currencyFormat = NumberFormat.getCurrencyInstance(Locale.US);
           
        public ShoppingCartServlet() {
            super();
        }
    
        @Override
        public void init() throws ServletException {
            products.add(new Product(1, "Bravo 32' HDTV", "Low-cost HDTV from renowned TV manufacturer", 159.95F));
            products.add(new Product(2, "Bravo BluRay Player", "High quality stylish BluRay palyer", 99.95F));
            products.add(new Product(3, "Bravo Stereo system", "5 speaker hifi system with ipod player", 129.95F));
            products.add(new Product(4, "Bravo ipod player", "An iPod plug-in that can play multiple formats", 39.95F));
        }
        
        private void sendProductList(HttpServletResponse response) throws IOException {
            response.setContentType("text/html");
            PrintWriter writer = response.getWriter();
            writer.println("<html>");
            writer.println("<head>");
            writer.println("<title>Products</title>");
            writer.println("<body>");
            writer.println("<h2>Products</h2>");
            writer.println("<ul>");
            for (Product product : products) {
                writer.println("<li>" + product.getName() + " (" + currencyFormat.format(product.getPrice()) + ") (" + "<a href='viewProductDetails?id="+ product.getId() + "'>Details)</a></li>");
            }
            writer.println("</ul>");
            writer.println("<a href='viewCart'>View Cart</a>");  // 一个超链接
            writer.println("</body>");
            writer.println("</html>");
        }
        
        private Product getProduct(int productId) {
            for (Product product : products) {
                if (product.getId() == productId) {
                    return product;
                }
            }
            return null;
        }
        
        private void sendProductDetails(HttpServletRequest request, HttpServletResponse response) throws IOException {
            response.setContentType("text/html");
            PrintWriter writer = response.getWriter();
            int productId = 0;
            try {
                productId = Integer.parseInt(request.getParameter("id"));  // 获取uri后端的请求字符串
            } catch (NumberFormatException e) {
                e.printStackTrace();
            }
            Product product = getProduct(productId);
            if (product != null) {
                writer.println("<html>");
                writer.println("<head>");
                writer.println("<title>Product Details</title>");
                writer.println("<body>");
                writer.println("<h2>Product Details</h2>");
                writer.println("<form method='post' action='addToCart'>");  // 提交方式为post, 目标地址为addToCart
                writer.println("<input type='hidden' name='id' value='" + productId + "' />");  // 表单隐藏域
                writer.println("<table>");
                writer.println("<tr>");
                writer.println("<td>Name:</td>");
                writer.println("<td>" + product.getName() + "</td>");
                writer.println("</tr>");
                writer.println("<tr>");
                writer.println("<td>Description:</td>");
                writer.println("<td>" + product.getDescription() + "</td>");
                writer.println("</tr>");
                writer.println("<tr>");
                writer.println("<td><input name='quantity' /></td>");  // 默认type="text"
                writer.println("<td><input type='submit' value='Buy'></td>");  // 提交按钮
                writer.println("</tr>");
                writer.println("<tr>");
                writer.println("<td colspan='2'><a href='products'>Product List</a></td>");  // 返回到产品列表的超链接
                writer.println("</tr>");
                writer.println("</table>");
                writer.println("</body>");
                writer.println("</html>");
            } else {
                writer.println("No product found");
            }
        }
        
        private void showCart(HttpServletRequest request, HttpServletResponse response) throws IOException {
            response.setContentType("text/html");
            PrintWriter writer = response.getWriter();
            writer.println("<html>");
            writer.println("<head>");
            writer.println("<title>Shopping Cart</title>");
            writer.println("</head>");
            writer.println("<body>");
            writer.println("<a href='products'>Product List</a>");  // 返回到产品列表的超链接
            HttpSession session = request.getSession();  // 获得当前的HttpSession对象
            List<ShoppingItem> cart = (List<ShoppingItem>)session.getAttribute(CART_ATTRIBUTE);
            if (cart != null) {
                writer.println("<table>");
                writer.println("<tr>");
                writer.println("<td style='150px'>Product</td>");  // 元素内嵌样式
                writer.println("<td style='150px'>Quantity</td>");
                writer.println("<td style='150px'>Price</td>");
                writer.println("<td style='150px'>Amount</td>");
                writer.println("<tr>");
                double total = 0.0;
                for (ShoppingItem shoppingItem : cart) {
                    Product product = shoppingItem.getProduct();
                    int quantity = shoppingItem.getQuantity();
                    if (quantity != 0) {
                        float price = product.getPrice();
                        double subtotal = price * quantity;
                        writer.println("<tr>");
                        writer.println("<td>" + product.getName() + "</td>");
                        writer.println("<td>" + quantity + "</td>");
                        writer.println("<td>" + currencyFormat.format(price) + "</td>");
                        writer.println("<td>" + currencyFormat.format(subtotal) + "</td>");
                        total += subtotal;
                        writer.println("</tr>");
                    }
                }
                writer.println("<tr>");
                writer.println("<td colspan='3' style='text-align:right'>Total: </td>");
                writer.println("<td>" + currencyFormat.format(total) + "</td>");
                writer.println("</tr>");
                writer.println("</table>");
            }
            writer.println("</body>");
            writer.println("</html>");
        }
        
        @Override
        protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
            String uri = request.getRequestURI();
            if (uri.endsWith("/products")) {  // 根据不同的uri调用不同的方法处理
                sendProductList(response);
            }else if (uri.endsWith("/viewProductDetails")) {
                sendProductDetails(request, response);
            }else if (uri.endsWith("viewCart")) {
                showCart(request, response);
            }
        }
    
        protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
            int productId = 0;
            int quantity = 0;
            try {
                productId = Integer.parseInt(request.getParameter("id"));       // 即可以或的token的值
                quantity = Integer.parseInt(request.getParameter("quantity"));  // 也可以获的表单隐藏域的值
            } catch (NumberFormatException e) {
                e.printStackTrace();
            }
            Product product = getProduct(productId);
            if (product != null) {
                ShoppingItem shoppingItem = new ShoppingItem(product, quantity);
                HttpSession session = request.getSession();  // HttpSession对象被自动创建,该方法可以获得httpSession对象
                List<ShoppingItem> cart = (List<ShoppingItem>) session.getAttribute(CART_ATTRIBUTE);
                if (cart == null) {
                    cart = new ArrayList<ShoppingItem>();
                    session.setAttribute(CART_ATTRIBUTE, cart);  // 向HttpSession对象绑定数据
                }
                cart.add(shoppingItem);
            }
            sendProductList(response);
        }
    }

     

  • 相关阅读:
    C#--C/S--学员管理系统--6--班级和下拉框的数据绑定
    C#--C/S--学员管理系统--5--通用验证类的设计和程序退出
    1046. 最后一块石头的重量
    1029. 两地调度
    1005. K 次取反后最大化的数组和
    944. 删列造序
    874. 模拟行走机器人
    860. 柠檬水找零
    map按值排序
    map按键排序
  • 原文地址:https://www.cnblogs.com/0820LL/p/9827710.html
Copyright © 2020-2023  润新知