💎一站式轻松地调用各大LLM模型接口,支持GPT4、智谱、星火、月之暗面及文生图 广告
# 步骤1:页面效果 首先访问 http://127.0.0.1:8080/tmall_j2ee/admin\_category\_list 观看页面效果 注: 刚开始看不到分类数据,分类数据需要自己添加 ![](https://box.kancloud.cn/6f8d32e68d7e466b7e2ce42fe48edec1_1828x443.png) # 步骤 2 : MVC 设计思想 根据**MVC设计模式**的思想,做J2EE web应用,从MVC的角度来看,就是把不同的数据显示在不同的页面上。 数据就是**模型**( bean, dao ) 页面就是**视图**( jsp ) 控制不同的模型显示在不同的视图上,这件事,就是由**控制器**来完成 ( servlet ) 所以分类管理,从MVC的角度来看,就是把多条分类Category数据放在一个集合里, 让listCategory.jsp 这个视图去显示出来。 ![](https://box.kancloud.cn/917d73b1508fec094265903d8d85840b_380x322.png) # 步骤 3 : list()方法 根据**filter+servlet的设计模式**,访问地址 http://127.0.0.1:8080/tmall_j2ee/admin\_category\_list 会导致CategoryServlet的list方法被调用。 根据**MVC 设计思想**,CategoryServlet充当的是C-控制器的角色 那么在list()方法里做的事情是,取出数据,并且交由jsp显示。 第二行: 通过categoryDAO取得数据集合 cs 第六行: 通过request.setAttribute 放在 “thecs" 这个key中,为后续服务端跳转到jsp之后使用。 第九行:return "admin/listCategory.jsp"; 服务端跳转到视图listCategory.jsp页面。 注:CategoryServlet的list()方法中可以直接使用categoryDao ,是因为其父类BaseBackServlet在属性中声明了 ``` public CategoryDao categoryDao = new CategoryDaoImpl(); ``` 作为BaseBackServlet的子类,CategoryServlet可以直接使用该public修饰的属性 ``` public String list(HttpServletRequest request, HttpServletResponse response) { List<Category> cs = categoryDao.list(); request.setAttribute("thecs", cs); return "admin/listCategory.jsp"; } ``` > 分页功能在后面添加。 # 步骤 4 : 服务端跳转 list()方法返回字符串 "admin/listCategory.jsp" 就导致服务端跳转到了页面 "admin/listCategory.jsp"。 为什么返回这个字符串,就可以实现**服务端跳转**呢? 在servlet中进行服务端跳转不是要如下代码格式吗? ``` request.getRequestDispatcher("xxx.jsp").forward(request, response); ``` 这个就要结合CategoryServlet的父类BaseBackServlet来理解了。 在BaseBackServlet,在借助反射机制调用了list()方法之后,获取返回值redirect,然后根据返回值进行处理: * 如果redirect是以@开头的字符串,那么就进行客户端跳转 * 如果redirect是以%开头的字符串,那么就直接输出字符串 * 如果都不是,则进行服务端跳转 ``` package com.dodoke.controller; import java.lang.reflect.Method; import javax.servlet.annotation.WebServlet; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import com.dodoke.dao.impl.CategoryDaoImpl; import com.dodoke.dao.inter.CategoryDao; /** * Servlet implementation class BaseBackServlet */ @WebServlet("/BaseBackServlet") public abstract class BaseBackServlet extends HttpServlet { private static final long serialVersionUID = 1L; public abstract String add(HttpServletRequest request, HttpServletResponse response); public abstract String delete(HttpServletRequest request, HttpServletResponse response); public abstract String edit(HttpServletRequest request, HttpServletResponse response); public abstract String update(HttpServletRequest request, HttpServletResponse response); public abstract String list(HttpServletRequest request, HttpServletResponse response); public CategoryDao categoryDao = new CategoryDaoImpl(); public void service(HttpServletRequest request, HttpServletResponse response) { try { /* 借助反射,调用对应的方法 */ String method = (String) request.getAttribute("method"); Method m = this.getClass().getMethod(method, javax.servlet.http.HttpServletRequest.class, javax.servlet.http.HttpServletResponse.class); String redirect = m.invoke(this, request, response).toString(); /* 根据方法的返回值,进行相应的客户端跳转,服务端跳转,或者仅仅是输出字符串 */ System.out.println(redirect); if (redirect.startsWith("@")) { response.sendRedirect(redirect.substring(1)); } else if (redirect.startsWith("%")) { response.getWriter().print(redirect.substring(1)); } else { request.getRequestDispatcher(redirect).forward(request, response); } } catch (Exception e) { e.printStackTrace(); throw new RuntimeException(e); } } } ``` # 步骤5:listCategory.jsp 最后就是视图listCategory.jsp了。 在**JSP包含关系**中已经讲解过了listCategory.jsp中包含的jsp文件,这里就不做赘述。 本步骤就关注在listCategory.jsp主体内容是如何工作的。 作为视图,担当的角色是显示数据。所以关键就是从第44行开始,借助JSTL的c:forEach标签遍历从CategoryServlet的list() 的request.setAttribute("thecs", cs); 传递过来的集合。 ``` <c:forEach items="${thecs}" var="c"> ``` ``` <%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8" import="java.util.*"%> <%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c"%> <%@include file="../include/admin/adminHeader.jsp"%> <%@include file="../include/admin/adminNavigator.jsp"%> <script> $(function(){ $("#addForm").submit(function(){ if(!checkEmpty("name","分类名称")) return false; if(!checkEmpty("categoryPic","分类图片")) return false; return true; }); }); </script> <title>分类管理</title> <div class="workingArea"> <h1 class="label label-info" >分类管理</h1> <br> <br> <div class="listDataTableDiv"> <table class="table table-striped table-bordered table-hover table-condensed"> <thead> <tr class="success"> <th>ID</th> <th>图片</th> <th>分类名称</th> <!-- <th>属性管理</th> --> <!-- <th>产品管理</th> --> <th>编辑</th> <th>删除</th> </tr> </thead> <tbody> <c:forEach items="${thecs}" var="c"> <tr> <td>${c.id}</td> <td><img height="40px" src="img/category/${c.id}.jpg"></td> <td>${c.name}</td> <%-- <td><a href="admin_property_list?cid=${c.id}"><span class="glyphicon glyphicon-th-list"></span></a></td> --%> <%-- <td><a href="admin_product_list?cid=${c.id}"><span class="glyphicon glyphicon-shopping-cart"></span></a></td> --%> <td><a href="admin_category_edit?id=${c.id}"><span class="glyphicon glyphicon-edit"></span></a></td> <td><a deleteLink="true" href="admin_category_delete?id=${c.id}"><span class=" glyphicon glyphicon-trash"></span></a></td> </tr> </c:forEach> </tbody> </table> </div> <%-- <div class="pageDiv"> <%@include file="../include/admin/adminPage.jsp" %> </div> --%> <div class="panel panel-warning addDiv"> <div class="panel-heading">新增分类</div> <div class="panel-body"> <form method="post" id="addForm" action="admin_category_add" enctype="multipart/form-data"> <table class="addTable"> <tr> <td>分类名称</td> <td><input id="name" name="name" type="text" class="form-control"></td> </tr> <tr> <td>分类圖片</td> <td> <input id="categoryPic" accept="image/*" type="file" name="filepath" /> </td> </tr> <tr class="submitTR"> <td colspan="2" align="center"> <button type="submit" class="btn btn-success">提 交</button> </td> </tr> </table> </form> </div> </div> </div> <%@include file="../include/admin/adminFooter.jsp"%> ```