# 步骤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"%>
```
- 项目简介
- 功能一览
- 前台
- 后台
- 开发流程
- 需求分析-展示
- 首页
- 产品页
- 分类页
- 搜索结果页
- 购物车查看页
- 结算页
- 确认支付页
- 支付成功页
- 我的订单页
- 确认收货页
- 评价页
- 页头信息展示
- 需求分析-交互
- 分类页排序
- 立即购买
- 加入购物车
- 调整订单项数量
- 删除订单项
- 生成订单
- 订单页功能
- 确认付款
- 确认收货
- 提交评价信息
- 登录
- 注册
- 退出
- 搜索
- 前台需求列表
- 需求分析后台
- 分类管理
- 属性管理
- 产品管理
- 产品图片管理
- 产品属性设置
- 用户管理
- 订单管理
- 后台需求列表
- 表结构设计
- 数据建模
- 表与表之间的关系
- 实体类设计
- DAO类设计
- 工具类
- CategoryDao设计
- Service业务类设计
- 后台-分类管理
- 可运行的项目
- 静态资源
- FILTER配合SERVLET
- JSP包含关系
- 查询
- 分页
- 增加
- 删除
- 编辑
- 修改
- 后台其他管理
- 属性管理
- 产品管理
- 产品图片管理
- 产品属性值设置
- 用户管理
- 订单管理