zl程序教程

您现在的位置是:首页 >  后端

当前栏目

《Servlet、JSP和Spring MVC初学指南》——2.4 HttpSession对象

SpringJSP对象ServletMVC 指南 2.4 初学
2023-09-11 14:17:32 时间
没有参数的getSession方法会返回当前的HttpSession,若当前没有,则创建一个返回。getSession(false)返回当前HttpSession,如当前存在,则返回null。getSession(true)返回当前HttpSession,若当前没有,则创建一个getSession(true)同getSession()一致。

本节书摘来自异步社区《Servlet、JSP和Spring MVC初学指南》一书中的第2章,第2.4节,作者:【加】Budi Kurniawan(克尼亚万) , 【美】Paul Deck著,更多章节内容可以访问云栖社区“异步社区”公众号查看

2.4 HttpSession对象

在所有的会话跟踪技术中,HttpSession 对象是最强大和最通用的。一个用户可以有且最多有一个HttpSession,并且不会被其他用户访问到。

HttpSession对象在用户第一次访问网站的时候自动被创建,你可以通过调用HttpServletRequest的getSession方法获取该对象。getSession有两个重载方法:

HttpSession getSession()

HttpSession getSession(boolean create)

没有参数的getSession方法会返回当前的HttpSession,若当前没有,则创建一个返回。getSession(false)返回当前HttpSession,如当前存在,则返回null。getSession(true)返回当前HttpSession,若当前没有,则创建一个getSession(true)同getSession()一致。

可以通过HttpSession的setAttribute方法将值放入HttpSession,该方法签字如下:

void setAttribute(java.lang.String name, java.lang.Object value)
请注意,不同于URL重新、隐藏域或cookie,放入到HttpSession 的值,是存储在内存中的,因此,不要往HttpSession放入太多对象或大对象。尽管现代的Servlet容器在内存不够用的时候会将保存在HttpSessions的对象转储到二级存储上,但这样有性能问题,因此小心存储。

此外,放到HttpSession的值不限于String类型,可以是任意实现java.io.Serializable的java对象,因为Servlet容器认为必要时会将这些对象放入文件或数据库中,尤其在内存不够用的时候,当然你也可以将不支持序列化的对象放入HttpSession,只是这样,当Servlet容器视图序列化的时候会失败并报错。

调用setAttribute方法时,若传入的name参数此前已经使用过,则会用新值覆盖旧值。
通过调用HttpSession的getAttribute方法可以取回之前放入的对象,该方法的签名如下:

java.lang.Object getAttribute(java.lang.String name)
HttpSession 还有一个非常有用的方法,名为getAttributeNames,该方法会返回一个Enumeration 对象来迭代访问保存在HttpSession中的所有值:

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

可以通过调用 HttpSession的getId方法来读取该标识:

java.lang.String getId()
此外,HttpSession.还定义了一个名为invalidate 的方法。该方法强制会话过期,并清空其保存的对象。默认情况下,HttpSession 会在用户不活动一段时间后自动过期,该时间可以通过部署描述符的 session-timeout 元素配置,若设置为30,则会话对象会在用户最后一次访问30分钟后过期,如果部署描述符没有配置,则该值取决于Servlet容器的设定。

大部分情况下,你应该主动销毁无用的HttpSession,以便释放相应的内存。

可以通过调用HttpSession 的getMaxInactiveInterval 方法来查看会话多久会过期。该方法返回一个数字类型,单位为秒。调用setMaxInactiveInterval 方法来单独对某个HttpSession 设定其超时时间:

void setMaxInactiveInterval(int seconds)
若设置为0,则该HttpSession 永不过期。通常这不是一个好的设计,因此该 HttpSession 所占用的堆内存将永不释放,直到应用重加载或Servlet容器关闭。

清单2.9 ShoppingCartServlet 为一个小的有4个商品的在线商城,用户可以将商品添加到购物车中,并可以查看购物车内容,所用到的Product类可见清单2.7,ShoppingItem 类可见清单2.8,Product类定义了4个属性(id、name、description和price),ShoppingItem 有两个属性,即quantity和Product。
清单2.7 Product类

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;

 // get and set methods not shown to save space

}

清单2.8 ShoppingItem类

package app02a.httpsession;

public class ShoppingItem {

 private Product product;

 private int quantity;

 public ShoppingItem(Product product, int quantity) {

 this.product = product;

 this.quantity = quantity;

 // get and set methods not shown to save space

}

清单2.9 ShoppingCartServlet类

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 = -20L;

 private static final String CART_ATTRIBUTE = "cart";

 private List Product products = new ArrayList Product 

 private NumberFormat currencyFormat = NumberFormat

 .getCurrencyInstance(Locale.US);

 @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 player", 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));

 @Override

 public void doGet(HttpServletRequest request,

 HttpServletResponse response) throws ServletException,

 IOException {

 String uri = request.getRequestURI();

 if (uri.endsWith("/products")) {

 sendProductList(response);

 } else if (uri.endsWith("/viewProductDetails")) {

 sendProductDetails(request, response);

 } else if (uri.endsWith("viewCart")) {

 showCart(request, response);

 @Override

 public void doPost(HttpServletRequest request,

 HttpServletResponse response) throws ServletException,

 IOException {

 // add to cart

 int productId = 0;

 int quantity = 0;

 try {

 productId = Integer.parseInt(

 request.getParameter("id"));

 quantity = Integer.parseInt(request

 .getParameter("quantity"));

 } catch (NumberFormatException e) {

 Product product = getProduct(productId);

 if (product != null quantity = 0) {

 ShoppingItem shoppingItem = new ShoppingItem(product,

 quantity);

 HttpSession session = request.getSession();

 List ShoppingItem cart = (List ShoppingItem ) session

 .getAttribute(CART_ATTRIBUTE);

 if (cart == null) {

 cart = new ArrayList ShoppingItem 

 session.setAttribute(CART_ATTRIBUTE, cart);

 cart.add(shoppingItem);

 sendProductList(response);

 private void sendProductList(HttpServletResponse response)

 throws IOException {

 response.setContentType("text/html");

 PrintWriter writer = response.getWriter();

 writer.println(" html head title Products /title " +

 " /head body 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 

 writer.println(" /ul 

 writer.println(" a href=viewCart View Cart /a 

 writer.println(" /body /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"));

 } catch (NumberFormatException e) {

 Product product = getProduct(productId);

 if (product != null) {

 writer.println(" html head "

 + " title Product Details /title /head "

 + " body h2 Product Details /h2 "

 + " form method=post action=addToCart 

 writer.println(" input type=hidden name=id "

 + "value=" + productId + "/ 

 writer.println(" table 

 writer.println(" tr td Name: /td td "

 + product.getName() + " /td /tr 

 writer.println(" tr td Description: /td td "

 + product.getDescription() + " /td /tr 

 writer.println(" tr " + " tr "

 + " td input name=quantity/ /td "

 + " td input type=submit value=Buy/ "

 + " /td "

 + " /tr 

 writer.println(" tr td colspan=2 "

 + " a href=products Product List /a "

 + " /td /tr 

 writer.println(" /table 

 writer.println(" /form /body 

 } 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 head title Shopping Cart /title "

 + " /head 

 writer.println(" body a href=products " +

 "Product List /a 

 HttpSession session = request.getSession();

 List ShoppingItem cart = (List ShoppingItem ) session

 .getAttribute(CART_ATTRIBUTE);

 if (cart != null) {

 writer.println(" table 

 writer.println(" tr td Quantity"

 + " /td "

 + " td Product /td "

 + " td Price /td "

 + " td Amount /td /tr 

 double total = 0.0;

 for (ShoppingItem shoppingItem : cart) {

 Product product = shoppingItem.getProduct();

 int quantity = shoppingItem.getQuantity();

 if (quantity != 0) {

 float price = product.getPrice();

 writer.println(" tr 

 writer.println(" td " + quantity + " /td 

 writer.println(" td " + product.getName()

 + " /td 

 writer.println(" td "

 + currencyFormat.format(price)

 + " /td 

 double subtotal = price * quantity;

 writer.println(" td "

 + currencyFormat.format(subtotal)

 + " /td 

 total += subtotal;

 writer.println(" /tr 

 writer.println(" tr td colspan=4 "

 + " "

 + "Total:"

 + currencyFormat.format(total)

 + " /td /tr 

 writer.println(" /table 

 writer.println(" /table /body /html 

}

ShoppingCartServlet 映射有如下URL:

/products:显示所有商品。
/viewProductDetails:展示一个商品的细节。
/addToCart:将一个商品添加到购物车中。
/viewCart:展示购物车的内容。
除/addToCart外,其他URL都会调用doGet方法。doGet 首先根据所请求的URL来生成相应内容:

String uri = request.getRequestURI();

 if (uri.endsWith("/products")) {

 sendProductList(response);

 } else if (uri.endsWith("/viewProductDetails")) {

 sendProductDetails(request, response);

 } else if (uri.endsWith("viewCart")) {

 showCart(request, response);

如下URL访问应用的主界面:

http://localhost:8080/app02a/products
该URL会展示商品列表,如图2.9所示。
screenshot
单击Details(详细)链接,Servlet会显示所选产品的详细信息,如图2.10所示。请注意页面上的输入框和Buy按钮,输入一个数字并单击Buy按钮,就可以添加该产品到购物车中。
screenshot
提交购物表单,Web容器会调用ShoppingCartServlet的doPost方法,该方法将一个商品添加到该用户的HttpSession。

doPost方法首先构造一个ShoppingItem实例,传入用户所编辑的商品和数量:

 ShoppingItem shoppingItem = new ShoppingItem(product,

 quantity);

然后获取当前用户的HttpSession,并检查是否已经有一个名为“cart”的List对象:

 HttpSession session = request.getSession();

 List ShoppingItem cart = (List ShoppingItem ) session

 .getAttribute(CART_ATTRIBUTE);

若不存在,则创建一个并添加到HttpSession中:

if (cart == null) {

 cart = new ArrayList ShoppingItem 

 session.setAttribute(CART_ATTRIBUTE, cart);

最后,将所创建的ShoppingItem添加到该list中:

 cart.add(shoppingItem);

当用户单击View Cart(查看购物车)链接时,Web容器调用showCart方法,获取当前用户的HttpSession并调用其getAttribute方法来获取购物商品列表:

 HttpSession session = request.getSession();

 List ShoppingItem cart = (List ShoppingItem ) session

 .getAttribute(CART_ATTRIBUTE);

然后迭代访问List对象,并将购物项发送给浏览器:

 if (cart != null) {

 for (ShoppingItem shoppingItem : cart) {

 Product product = shoppingItem.getProduct();

 int quantity = shoppingItem.getQuantity();

 …

Spring Boot MVC请求参数通用校验及国际化支持 一、Validation及国际化配置 1、添加依赖 2、校验失败提示消息国际化配置 3、application.properties 4、国际化资源文件 二、代码演示 1、全局异常处理 2、MessageUtils工具类 3、响应VO 2、测试Controller和请求DTO 3、多语言属性文件 4、测试用例 (1)简单对象UserReqDTO测试 (2)包含List集合对象的ChargeRuleReqDTO测试
Spring MVC中文件上传和下载 文件上传需将表格的提交方式设为 POST ,并且将enctype设为 multipart/form-data ,以二进制的方式提交数据。 spring mvc中可通过MultipartResolver监听每个请求,如有上传的文件,则把请求封装为MultipartHttpServletRequest,通过封装的请求可以获取上传的文件信息和上传的文件。 实际使用可直接将MultipartFile作为控制器中请求处理方法的参数,MultipartFile是一个接口,其实现类为CommonsMultipartFile,通过MultipartFile封装的方法也可获取文件相关信息。
java面试题(十八)spring MVC 3.1 什么是MVC? MVC是一种设计模式,在这种模式下软件被分为三层,即Model(模型)、View(视图)、Controller(控制器)。Model代表的是数据,View代表的是用户界面,Controller代表的是数据的处理逻辑,它是Model和View这两层的桥梁。将软件分层的好处是,可以将对象之间的耦合度降低,便于代码的维护。 3.2 DAO层是做什么的? DAO是Data Access Object的缩写,即数据访问对象,在项目中它通常作为独立的一层,专门用于访问数据库。这一层的具体实现技术有很多,常用的有Spring JDBC、Hibernate、JPA、
异步社区 异步社区(www.epubit.com)是人民邮电出版社旗下IT专业图书旗舰社区,也是国内领先的IT专业图书社区,致力于优质学习内容的出版和分享,实现了纸书电子书的同步上架,于2015年8月上线运营。公众号【异步图书】,每日赠送异步新书。
Java Spring Boot开发实战系列课程【第15讲】:Spring Boot 2.0 API与Spring REST Docs实战 立即下载