前情提要:
在项目中想要对 thymeleaf 前端页面进行页面静态缓存的优化,比如商品列表页面,需要先访问controller的toList方法,在获取到页面的动态数据后,需要spring渲染我们的model数据到thymeleaf页面模板上。
但是如果在高并发的情境下,多个用户想要获取商品列表页面,那么就会对服务器造成一定的负担,然而由于商品列表只是拉去商品信息进行展示,没有什么业务逻辑性质,那么这种负担就变得没有什么必要。所以,我们需要对这样的请求进行优化,可以减轻服务器的负担,从而可以去处理其他业务复杂的处理。
页面静态缓存就是一种优化手段,也就是在第一次访问页面的时候就将页面的html及其数据保存在redis缓存(或其他缓存方法)中,当然为了了保证数据的时效性,也需要对该页面缓存数据设置一定的有效时间。然后,在下次访问同一个页面的时候,服务器收到这个请求,就先去缓存中查找是否保存该页面数据(并且是没过期的),就可以直接将该页面数据(作为字符串数据)返回了,否则就需要生成网页数据并需要手动渲染该页面,将页面缓存下来,再进行返回。
下面来看下是怎么优化的吧~
原方法
@RequestMapping("/to_list")
public String toList(Model model, MiaoshaUser miaoshaUser) {
List<GoodsVo> goodsVoList = goodsService.goodsVoList();
model.addAttribute("goodsList", goodsVoList);
return "goods_list"; //跳转转发到 goods_list 页面
}
优化后
@RequestMapping(value = "/to_list", produces = "text/html")
@ResponseBody
public String toList(HttpServletRequest httpServletRequest,
HttpServletResponse httpServletResponse,
Locale locale,
Model model,
MiaoshaUser miaoshaUser) {
// 先查redis中是否缓存了该页面
String goods_list_html = redisService.get(GoodsKey.getGoodsList, "", String.class);
if (goods_list_html != null) {
return goods_list_html;
}
//获取商品列表数据
List<GoodsVo> goodsVoList = goodsService.goodsVoList();
model.addAttribute("goodsList", goodsVoList);
//如果没有缓存则手动渲染
WebContext webContext = new WebContext(httpServletRequest, httpServletResponse, servletContext, locale, model.asMap());
goods_list_html = thymeleafViewResolver.getTemplateEngine().process("goods_list", webContext);
redisService.set(GoodsKey.getGoodsList, "", goods_list_html); //将渲染网页数据缓存在redis中
return goods_list_html; //手动渲染的 goods_list 页面
}
一般来说,在 springboot 1.x 中是使用 SpringWebContext 获取传输数据的上下文环境的,但是由于项目使用的是 springboot 2.x ,而在springboot 2.x 中已经弃用了 SpringWebContext 了,所以我就去查了下还可以使用什么类来替换,于是找到 IContext 的实现类WebContext(在org.thymeleaf.context.WebContext 下),测试过是可以使用的!
测试结果
在第一次访问后,可以在redis中查找到该页面的缓存数据
版权声明:本文为Eskiii原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。