黑马旅游网案例学习之分类数据展示功能(五)

该博客介绍了如何在Servlet中优化JSON序列化过程,通过在BaseServlet中封装序列化方法,提高代码复用性。同时,针对频繁查询的分类数据,采用Redis进行缓存优化,减轻数据库压力。在前端,使用AJAX请求获取分类数据并动态渲染到header.html。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

功能分析

效果
在这里插入图片描述
分析
在这里插入图片描述

(一)后台代码:

CategoryServlet

@WebServlet("/category/*")
public class CategoryServlet extends BaseServlet {

    private CategoryService service = new CategoryServiceImpl();

    /**
     * 查询所有
     * @param request
     * @param response
     * @throws ServletException
     * @throws IOException
     */
    public void findAll(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        //1.调用service查询所有
        List<Category> cs = service.findAll();
        //2.序列化json返回
       /* ObjectMapper mapper = new ObjectMapper();
        response.setContentType("application/json;charset=utf-8");
        mapper.writeValue(response.getOutputStream(),cs);*/
       writeValue(cs,response);
    }
}

CategoryService

public class CategoryServiceImpl implements CategoryService {

    private CategoryDao categoryDao = new CategoryDaoImpl();

    @Override
    public List<Category> findAll() {
        return categoryDao.findAll();
    }
}

CategoryDao

public class CategoryDaoImpl implements CategoryDao {

    private JdbcTemplate template = new JdbcTemplate(JDBCUtils.getDataSource());

    @Override
    public List<Category> findAll() {
        String sql = "select * from tab_category ";
        return template.query(sql,new BeanPropertyRowMapper<Category>(Category.class));
    }
}

(二)优化:在BaseServlet中封装了序列化json的方法

/**
 * 直接将传入的对象序列化为json,并且写回客户端
 * @param obj
 */
public void writeValue(Object obj,HttpServletResponse response) throws IOException {
    ObjectMapper mapper = new ObjectMapper();
    response.setContentType("application/json;charset=utf-8");
    mapper.writeValue(response.getOutputStream(),obj);
}

/**
 * 将传入的对象序列化为json,返回
 * @param obj
 * @return
 */
public String writeValueAsString(Object obj) throws JsonProcessingException {
    ObjectMapper mapper = new ObjectMapper();
    return mapper.writeValueAsString(obj);
}

CategoryServlet

public void findAll(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        List<Category> cs = service.findAll();
        /*ObjectMapper mapper = new ObjectMapper();
        response.setContentType("application/json;charset=utf-8");
        mapper.writeValue(response.getOutputStream(),cs);*/
        writeValue(cs,response);
    }

可以把其他的Servlet也优化一下

UserServlet


     * 查询单个对象

    public void findOne(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        //页面中用户姓名的提示信息功能
        //从session中获取登录用户
        Object user = request.getSession().getAttribute("user");
        //将user写回客户端
        /*ObjectMapper mapper = new ObjectMapper();
        response.setContentType("application/json;charset=utf-8");
        mapper.writeValue(response.getOutputStream(),user);*/
        writeValue(user,response);
    }

     * 登录功能
  
    public void login(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        //登录
        Map<String, String[]> map = request.getParameterMap();
        User user =new User();
        try {
            BeanUtils.populate(user,map);
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        } catch (InvocationTargetException e) {
            e.printStackTrace();
        }
     //   UserService service = new UserServiceImpl();
        User u = service.login(user);

        ResultInfo info = new ResultInfo();

        if (u == null){
            info.setFlag(false);
            info.setErrorMsg("用户名或密码错误");
        }
        if (u !=null && !"Y".equals(u.getStatus())){
            info.setFlag(false);
            info.setErrorMsg("您尚未激活,请激活");
        }
        if (u != null && "Y".equals(u.getStatus())){
            request.getSession().setAttribute("user",u);
            info.setFlag(true);
        }
        /*ObjectMapper mapper = new ObjectMapper();
        response.setContentType("application/json;charset=utf-8");
        mapper.writeValue(response.getOutputStream(),info);*/
        writeValue(info,response);
    }

(三)前台代码:header.html

前端的数据是假的数据,要删除掉
在这里插入图片描述
hader.html加载后,发送ajax请求,请求category/findAll

//查询分类数据
 $.get("category/findAll",{},function (data) {
     //[{cid:1,cname:国内游},{},{}]
     var lis = '<li class="nav-active"><a href="index.html">首页</a></li>';
     //遍历数组,拼接字符串(<li>)
     for (var i = 0; i < data.length; i++) {
         var li = '<li><a href="route_list.html">'+data[i].cname+'</a></li>';
         lis += li;
     }
     //拼接收藏排行榜的li,<li><a href="favoriterank.html">收藏排行榜</a></li>
     
     lis+= '<li><a href="favoriterank.html">收藏排行榜</a></li>';

     //将lis字符串,设置到ul的html内容中
     $("#category").html(lis);
 });

(四)对分类数据进行缓存优化

分析发现,分类的数据在每一次页面加载后都会重新请求数据库来加载,对数据库的压力比较大,而且分类的数据不会经常产生变化,所有可以使用redis来缓存这个数据。
分析:
在这里插入图片描述
优化代码实现
期望数据中存储的顺序就是将来展示的顺序,使用redis的sortedset
CategoryServiceImpl:

public class CategoryServiceImpl implements CategoryService {

    private CategoryDao categoryDao = new CategoryDaoImpl();

    /**
     * 查询所有
     *
     * @return
     */

    @Override
    public List<Category> findAll() {
        Jedis jedis = JedisUtil.getJedis();
        Set<Tuple> categorys = jedis.zrangeWithScores("category", 0, -1);
        List<Category> cs = null;
        if (categorys == null || categorys.size() == 0){
            System.out.println("从数据库查询....");
            cs = categoryDao.findAll();
            for (int i = 0; i < cs.size(); i++){
                jedis.zadd("category",cs.get(i).getCid(),cs.get(i).getCname());
            }
        }else {
            System.out.println("从redis中查询...");
            cs = new ArrayList<Category>();
            for (Tuple tuple : categorys){
                Category category = new Category();
                category.setCname(tuple.getElement());
                category.setCid((int) tuple.getScore());
                cs.add(category);
            }
        }
        return cs;
    }
}

启动redis
在这里插入图片描述
然后查询数据库
在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值