根据上一篇的设计,猫哥想实现的是对于类似的某种实体概念(比如人员)的增删改查操作,将相似的逻辑封装一下,不用每次都写重复的部分。扯得远了点,直接看具体如何实现的:
在具体实现之前,先展示下效果,需要注意,猫哥将表格美工,内容部分美工,整个后台页面美工的css文件都单独抽取出来了,因为css不是本系列的重点且此前已经详细讲过了,此处不再贴代码。
a,登录成功后
b,点击人员管理后
c,点击人员编码7右边对应的删除后
d,点击人员编码2右边对应的编辑后
e,点击保存后
1,首先就是菜单信息的参数化,因为增、删、改、查等功能都是规定好的以/HomeworkSystem/AcitonServlet?method=XXX&entity=YYY&id=ZZZ
中的参数为区分,所以将Constant类修改为:
package util;
import java.util.HashMap;
public class Constant {//保存常量信息
//roleMenu用于保存角色及对应的菜单信息
public static HashMap<String,String[][]> roleMenu=new HashMap<String,String[][]>();
//使用static代码块对roleMenu进行初始化
static{
//注意,二位数组中的每一组表示一个菜单的信息,又通过map建立了角色名和菜单直接的对应关系
roleMenu.put("校长", new String[][]{
{"人员管理","view","User"},//由具体的地址,变为抽象的参数
{"课程管理","view","Course"}
});
roleMenu.put("教师", new String[][]{});
roleMenu.put("学生", new String[][]{});
}
}
2,从登录页面到LoginServlet,登录录成功后跳转index.jsp,此时index.jsp中的菜单加载部分需要修改如一下,主要有两处,一是菜单栏每一个菜单href属性指向参数化了,二是右侧内容区对应网址修改为actionUrl,猫哥感觉actionUrl更能表达此刻的心意,哈哈。
<%@ page language="java" import="java.util.*" pageEncoding="utf-8"%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %><!-- 使用c:标签需要添加本行代码 -->
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<title>index.jsp</title>
<link href="css/index.css" type="text/css" rel="stylesheet"/>
</head>
<body>
<div id="main">
<div id="top">
<div id="top_title">
猫哥培训班作业管理系统
</div><!-- 标题部分 -->
<div id="top_info">
欢迎您,尊敬的:${loginUser.userName}
</div><!-- 登录用户信息部分 -->
</div><!-- top部分是标题栏 -->
<div id="left">
<ul>
<c:forEach items="${loginRoleMenu}" var="menu">
<li>
<a href="/HomeworkSystem/ActionServlet?method=${menu[1]}&entity=${menu[2]}">${menu[0]}</a>
</li>
</c:forEach>
</ul>
</div><!-- left部分是菜单栏 -->
<div id="right">
<c:if test="${empty actionUrl}">
欢迎来到猫哥培训班管理系统
</c:if>
<c:if test="${not empty actionUrl}">
<jsp:include page="${actionUrl}" flush="true"></jsp:include>
</c:if>
</div><!-- right部分是具体内容显示区 -->
</div>
</body>
</html>
3,好的,来到CRUD操作控制的核心ActionServlet了,此时都是使用if判断的,针对不同的网页请求,采用不同的处理操作:
package servlet;
import java.io.IOException;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import command.ActionCommand;
import entity.*;
import java.util.List;
public class ActionServlet extends HttpServlet {
public void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
this.doPost(request, response);//doGet与doPost一样处理
}
public void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
//输入输出设置
response.setContentType("text/html");
request.setCharacterEncoding("utf-8");
response.setCharacterEncoding("utf-8");
//获取标准Action动作的三个参数
String method=request.getParameter("method");
String entityType=request.getParameter("entity");
String id=request.getParameter("id");
//处理
String actionUrl=doAction(request,method,entityType,id);
request.setAttribute("actionUrl",actionUrl);
//跳转
request.getRequestDispatcher("/index.jsp").forward(request,response);
}
//具体细分的控制处理,返回内容区域应该显示的网页地址
private String doAction(HttpServletRequest request,String method,String entityType,String entityId){
String url="";//初始化返回值
ActionCommand actionCommand=new ActionCommand(entityType);//处理数据库逻辑
if(method.equals("view")){//查看
List entityList=actionCommand.selectAll();
request.setAttribute("entityList",entityList);
url=entityType.toLowerCase()+"Manage.jsp";
}else if(method.equals("delete")){//删除
actionCommand.deleteById(entityId);
List entityList=actionCommand.selectAll();
request.setAttribute("entityList",entityList);//更新名单
url=entityType.toLowerCase()+"Manage.jsp";
}else if(method.equals("edit")){//修改
Object entity=actionCommand.selectById(entityId);
request.setAttribute("editEntity", entity);
url=entityType.toLowerCase()+"Update.jsp";
}else if(method.equals("add")){//新增
url=entityType.toLowerCase()+"Update.jsp";
}else if(method.equals("save")){//保存
//因保存时各类实体代码各不一致,导致写在此处会很难看,所以由单独提取成一个方法
this.doSaveAction(request,entityType,actionCommand);
List entityList=actionCommand.selectAll();
request.setAttribute("entityList",entityList);//更新名单
url=entityType.toLowerCase()+"Manage.jsp";
}
return url;
}
//单独处理save,因为save方法是跟具体的实体类结构相关
private void doSaveAction(HttpServletRequest request,String entityType,ActionCommand actionCommand){
String id=request.getParameter("hiddenId");
Object entity=null;
//-------------------------------------------------------------------------------
//此处为组装区域,根据不同页面内容是变化的,其余部分都是按一定规则固定了的
if(entityType.equals("User")){
User user=new User();
if(!"".equals(id))//修改
user.setUserId(Integer.parseInt(id));
else//新增
user.setUserPassword("1234");//初始化密码
user.setUserName(request.getParameter("userName"));
Role role=new Role();
role.setRoleId(Integer.parseInt(request.getParameter("userRole")));
user.setUserRole(role);
entity=user;
}
//-------------------------------------------------------------------------------
//实体修改到数据库
if(!"".equals(id)){//修改
actionCommand.update(entity);
}else{//添加
actionCommand.add(entity);
}
}
}
4,其中数据库操作部分是调用ActionCommand实现的,ActionCommand具体如下:
package command;
import java.util.List;
import javax.servlet.http.HttpServletRequest;
import entity.*;
import operation.*;
public class ActionCommand{
private String entityType;
public ActionCommand(String type){
entityType=type;
}
public List selectAll(){
ObjectOperation oper=OperationFactory.createOperation(entityType);
return oper.selectAll();
}
public int deleteById(String id){
ObjectOperation oper=OperationFactory.createOperation(entityType);
return oper.deleteById(id);
}
public Object selectById(String id){
ObjectOperation oper=OperationFactory.createOperation(entityType);
return oper.selectById(id);
}
public int add(Object entity){
ObjectOperation oper=OperationFactory.createOperation(entityType);
return oper.add(entity);
}
public int update(Object entity){
ObjectOperation oper=OperationFactory.createOperation(entityType);
return oper.update(entity);
}
}
发现ActionCommand的代码倒是非常精简啊,因为本来就是要增删改查嘛。好的,至于数据库操作层的代码,此处就不细讲了,需要的可自行翻看以前的章节。
5,下面先来实现人员管理的列表页面userManage.jsp如下:
<%@ page language="java" import="java.util.*" pageEncoding="utf-8"%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %><!-- 使用c:标签需要添加本行代码 -->
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<title>userManage.jsp</title>
<link href="css/content.css" type="text/css" rel="stylesheet"/>
<link href="css/table.css" type="text/css" rel="stylesheet"/>
</head>
<body>
<div id="user_top">
人员管理
</div><!-- user_top end -->
<div id="user_mid">
<table class="table_theme1">
<thead>
<th>人员编码</th>
<th>姓名</th>
<th>角色</th>
<th>操作</th>
<th>操作</th>
</thead>
<c:forEach items="${entityList}" var="item">
<tr>
<td>${item.userId}</td>
<td>${item.userName}</td>
<td>${item.userRole.roleName}</td>
<td><a href="/HomeworkSystem/ActionServlet?method=edit&entity=User&id=${item.userId}">编辑</a></td>
<td><a href="/HomeworkSystem/ActionServlet?method=delete&entity=User&id=${item.userId}">删除</a></td>
</tr>
</c:forEach>
</table>
</div><!-- user_mid end -->
<div id="user_bottom">
<a href="/HomeworkSystem/ActionServlet?method=add&entity=User">新增</a>
</div><!-- "user_bottom" end -->
</body>
</html>
6,最后,实现人员管理修改/新增时的页面:
<%@ page language="java" import="java.util.*" pageEncoding="utf-8"%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %><!-- 使用c:标签需要添加本行代码 -->
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<title>userUpdate.jsp</title>
<link href="css/content.css" type="text/css" rel="stylesheet"/>
<link href="css/table.css" type="text/css" rel="stylesheet"/>
</head>
<body>
<form action="/HomeworkSystem/ActionServlet?method=save&entity=User" method="post">
<div id="user_top">
人员信息更新
</div><!-- user_top end -->
<div id="user_mid">
<table class="table_theme1">
<tr>
<td>姓名:</td>
<td>
<input type="text" name="userName" value="${editEntity.userName}"/>
<input type="hidden" name="hiddenId" value="${editEntity.userId}"/>
</td>
</tr>
<tr>
<td>角色:</td>
<td>
<select name="userRole"><!-- 编辑情况下,默认显示编辑用户的角色的功能,待后续优化项目时再讲如何实现 -->
<option value="1">校长</option>
<option value="2">老师</option>
<option value="3">学生</option>
</select>
</td>
</tr>
</table>
</div><!-- user_mid end -->
<div id="user_bottom">
<input type="submit" value="保存"></input>
</div><!-- "user_bottom" end -->
</form>
</body>
</html>
最后总结一下子,因为有了通用的CRUD后端,我们每次添加一个实体(比如课程、人员、角色等等)的增删改查功能时,只需要建立两个网页xxxManage.jsp和xxxUpdate.jsp,并按照规则修改里面的链接和具体信息(每种实体内容不同),然后在ActionServlet的
doSaveAction方法里添加新的if分支以保存新类型的实体就行了。
怎么感觉一下子就简单了呢,这样的一个通用CRUD后端设计合理吗,能实现所有功能吗,易拓展吗?这个问题留待下篇分解。