上一篇我把项目的整个结构搭好了,这里写一下Servlet的实现。
利用Servlet开发有一个弊端就是每一个请求URL都要有对应的Servlet与之对应,但是这样会造成Servlet臃肿,在web.xml中也会出现一大堆Servlet配置信息。为了解决这个问题,我这里利用给Servlet传一个action参数来使一个Servlet处理一类请求。
具体实现如下:
在Serlvet中创建一个数组,记录所有请求这个Servlet的操作,
1 private static final String[] action = { "", "save", "delete", "query", "update", "ajax-type" };
在doPost方法中根据参数action决定要调用的方法
1 protected void doPost(HttpServletRequest request, HttpServletResponse response) 2 throws ServletException, IOException { 3 // 获取action参数 4 String actionName = request.getParameter("action") != null ? request.getParameter("action") : ""; 5 int actionIndex = 0; 6 for (int i = 0; i < action.length; i++) { 7 if (action[i].equals(actionName)) { 8 actionIndex = i;// 记录要调用的方法 9 break; 10 } 11 } 12 13 // 保存action操作结果[d/r/"", url] 14 String[] r = null; 15 // 根据actionIndex调用对应的方法 16 switch (actionIndex) { 17 case 0: 18 r = index(request, response);// 调用首页方法 19 break; 20 case 1: 21 r = save(request, response); 22 break; 23 case 5: 24 r = ajaxType(request, response); 25 default: 26 // 如果找不到则转发到404.jsp页面 27 r = new String[] { "d", "WEB-INF/jsp/404.jsp" }; 28 break; 29 } 30 31 // 根据action操作结果执行相应的操作 32 if ("d".equals(r[0])) {// 转发 33 RequestDispatcher rd = request.getRequestDispatcher(r[1]); 34 rd.forward(request, response); 35 } else if ("r".equals(r[0])) {// 重定向 36 response.sendRedirect(r[1]); 37 } else {// 直接输出r[1]的内容 38 PrintWriter out = response.getWriter(); 39 out.println(r[1]); 40 out.flush(); 41 out.close(); 42 } 43 }
这样如果要调用Serlvet中的save方法处理请求就可以这样访问这个Serlvet,http://127.0.0.1:8080/projectName/servletName?action=save
这里所有Serlvet中的私有处理请求的方法都会返回一个String数组,这个数组包含两个对象,第一个是操作类型,可以是“r”或“d”或其他,其中“r”表示重定向,“d”表示转发,其他则将数组的第二个对象直接输出给客户端。第二个对象是要转发或重定向的url或要输出到客户端的字符串。
如下是Serlvet的save方法:
1 // 保存实体 2 private String[] save(HttpServletRequest request, HttpServletResponse response) { 3 String name = request.getParameter("name"); 4 if (name == null || "".equals(name)) {// 非空校验 5 request.setAttribute("msg", "类型名称不能为空"); 6 return new String[] { "d", "WEB-INF/jsp/type-save.jsp" }; 7 } 8 Type t = new Type(); 9 t.setName(name); 10 typeService.save(t); 11 12 String root = request.getContextPath(); 13 // 重定向,客户端跳转 14 return new String[] { "r", root + "/type" }; 15 }
下面是整个Servlet的完整代码如下(当然这里只用到了index函数,其他函数是后面的功能用到的):
TypeAction.java
1 package action; 2 3 import java.io.IOException; 4 import java.io.PrintWriter; 5 import java.util.List; 6 7 import javax.servlet.RequestDispatcher; 8 import javax.servlet.ServletException; 9 import javax.servlet.http.HttpServlet; 10 import javax.servlet.http.HttpServletRequest; 11 import javax.servlet.http.HttpServletResponse; 12 13 import model.Type; 14 import service.TypeService; 15 import service.impl.TypeServiceImpl; 16 import util.LogUtil; 17 18 public class TypeAction extends HttpServlet { 19 private static final long serialVersionUID = 1L; 20 21 private static final String[] action = { "", "save", "delete", "query", "update", "ajax-type" }; 22 // type 业务 23 private TypeService typeService = new TypeServiceImpl(); 24 25 protected void doGet(HttpServletRequest request, HttpServletResponse response) 26 throws ServletException, IOException { 27 doPost(request, response); 28 } 29 30 protected void doPost(HttpServletRequest request, HttpServletResponse response) 31 throws ServletException, IOException { 32 // 获取action参数 33 String actionName = request.getParameter("action") != null ? request.getParameter("action") : ""; 34 int actionIndex = 0; 35 for (int i = 0; i < action.length; i++) { 36 if (action[i].equals(actionName)) { 37 actionIndex = i;// 记录要调用的方法 38 break; 39 } 40 } 41 42 // 保存action操作结果[d/r/"", url] 43 String[] r = null; 44 // 根据actionIndex调用对应的方法 45 switch (actionIndex) { 46 case 0: 47 r = index(request, response);// 调用首页方法 48 break; 49 case 1: 50 r = save(request, response); 51 break; 52 case 5: 53 r = ajaxType(request, response); 54 default: 55 // 如果找不到则转发到404.jsp页面 56 r = new String[] { "d", "WEB-INF/jsp/404.jsp" }; 57 break; 58 } 59 60 // 根据action操作结果执行相应的操作 61 if ("d".equals(r[0])) {// 转发 62 RequestDispatcher rd = request.getRequestDispatcher(r[1]); 63 rd.forward(request, response); 64 } else if ("r".equals(r[0])) {// 重定向 65 response.sendRedirect(r[1]); 66 } else {// 直接输出r[1]的内容 67 PrintWriter out = response.getWriter(); 68 out.println(r[1]); 69 out.flush(); 70 out.close(); 71 } 72 } 73 74 // 首页 75 private String[] index(HttpServletRequest request, HttpServletResponse response) { 76 List<Type> tList = typeService.find(); 77 request.setAttribute("entities", tList); 78 return new String[] { "d", "WEB-INF/jsp/type-index.jsp" }; 79 } 80 81 // 保存实体 82 private String[] save(HttpServletRequest request, HttpServletResponse response) { 83 String name = request.getParameter("name"); 84 if (name == null || "".equals(name)) {// 非空校验 85 request.setAttribute("msg", "类型名称不能为空"); 86 return new String[] { "d", "WEB-INF/jsp/type-save.jsp" }; 87 } 88 Type t = new Type(); 89 t.setName(name); 90 typeService.save(t); 91 92 String root = request.getContextPath(); 93 // 重定向,客户端跳转 94 return new String[] { "r", root + "/type" }; 95 } 96 97 // 异步拉取type数据 98 private String[] ajaxType(HttpServletRequest request, HttpServletResponse response) { 99 List<Type> tList = typeService.find(); 100 StringBuffer json = new StringBuffer("{ \"total\" : ").append(tList.size()).append(", \"data\" : ["); 101 if (!tList.isEmpty()) { 102 for (int i = 0, size = tList.size(); i < size - 1; i++) { 103 json = json.append("{\"id\" : ").append(tList.get(i).getId()).append(", \"name\" : \"") 104 .append(tList.get(i).getName()).append("\"},"); 105 } 106 json = json.append("{\"id\" : ").append(tList.get(tList.size() - 1).getId()).append(", \"name\" : \"") 107 .append(tList.get(tList.size() - 1).getName()).append("\"}"); 108 } 109 json = json.append("]}"); 110 111 return new String[] { "", json.toString() }; 112 } 113 }
在web.xml配置Servlet
1 <servlet> 2 <servlet-name>TypeAction</servlet-name> 3 <servlet-class>action.TypeAction</servlet-class> 4 </servlet> 5 <servlet-mapping> 6 <servlet-name>TypeAction</servlet-name> 7 <url-pattern>/type</url-pattern> 8 </servlet-mapping>
说一下整个程序的流程:
- 客户端访问服务器 http://127.0.0.2:8080/goods-show/type,这里type没有action参数,如果没有参数则调用serlvet的index函数,如上面代码,action参数为null时,会被置为""。对应action数组的第一个元素,即case 0: r=index(request,response);break;
- index函数被调用,然后typeService.find()会从调用数据库操作查询所有类型实体,然后存在request转发给客户端,这里只能用转发,不能用重定向,否则request的数据将被清空,对于TypeService这个类将在下一篇说到,如下代码:
List<Type> tList = typeService.find(); request.setAttribute("entities", tList); return new String[] { "d", "WEB-INF/jsp/type-index.jsp" };
- index函数利用request.setAttribute("entities", tList);将数据存放在request中,这样在JSP页面中就可以利用EL表达式和JSTL来访问(这样可以做到在JSP中不存在java代码,方便解耦)。
- 修改前台静态页面,将其改成动态
1 <%@ page language="java" contentType="text/html; charset=UTF-8" 2 pageEncoding="UTF-8"%> 3 <!DOCTYPE> 4 <html> 5 <head> 6 <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> 7 <%@ include file="top.jsp"%> 8 <title>商品展示平台</title> 9 </head> 10 <body> 11 <div> 12 <div><a href="${root}/send?url=type-save.jsp">添加商品类型</a></div> 13 <c:forEach items="${entities}" var="obj"> 14 <div> 15 <a href="${root}/goods?action=tid&tid=${obj.id}">${obj.name}</a> 16 </div> 17 </c:forEach> 18 </div> 19 </body> 20 </html>
- 这里引用了一个共同的JSP——top.jsp,这个JSP是用来引入公共资源的,代码如下:
1 <%@ page language="java" contentType="text/html; charset=UTF-8" 2 pageEncoding="UTF-8"%> 3 <%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%> 4 <c:set var="root" value="${pageContext.request.contextPath}" /> 5 <link href="${root}/resources/css/main.css" rel="stylesheet" />
运行结果如下(这里的数据是我事先录入的,乱码情况将在最后使用Filter来处理):
以下是两个张表:
tb_type:
tb_goods:
TypeService等service层和DAO层的实现将在下一篇说到。
时间: 2024-10-10 06:36:08