JavaWeb

模仿SpringMVC抽取一个BaseServlet,接收所有请求,然后自动封装表单参数和分发到对应的servlet执行,下面用一个页面表单提交,转发显示的项目做示例。

1)首先准备一个Entity,用来封装表单提交的参数

 1 package com.qf.entity;
 2 
 3 public class User {
 4 
 5     private String name;
 6     
 7     private String password;
 8     
 9     private Integer age;
10 
11     public Integer getAge() {
12         return age;
13     }
14 
15     public void setAge(Integer age) {
16         this.age = age;
17     }
18 
19     public String getName() {
20         return name;
21     }
22 
23     public void setName(String name) {
24         this.name = name;
25     }
26 
27     public String getPassword() {
28         return password;
29     }
30 
31     public void setPassword(String password) {
32         this.password = password;
33     }
34 
35     @Override
36     public String toString() {
37         return "User [name=" + name + ", password=" + password + ", age=" + age + "]";
38     }
39     
40 }
User.java

2)前端表单

 1 <%@ page language="java" contentType="text/html; charset=UTF-8"
 2     pageEncoding="UTF-8"%>
 3 <%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
 4 <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
 5 <html>
 6 <head>
 7 <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
 8 <title>Insert title here</title>
 9 </head>
10 <body>
11 <form action="UserServlet?action=addUser" method="post">
12 姓名:<input type="text" name="name" /><br>
13 密码:<input type="text" name="password" /><br>
14 年龄:<input type="text" name="age" /><br>
15 <input type="submit" value="添加" /><br>
16 </form>
17 </body>
18 </html>
index.jsp

3)抽取BaseServlet,不需要再web.xml中注册,但要继承HttpServlet;主要通过反射来实现,具体的步骤已在代码中注释

  1 package com.qf.servlet;
  2 
  3 import java.io.IOException;
  4 import java.lang.reflect.Field;
  5 import java.lang.reflect.InvocationTargetException;
  6 import java.lang.reflect.Method;
  7 import java.lang.reflect.Parameter;
  8 
  9 import javax.servlet.ServletException;
 10 import javax.servlet.http.HttpServlet;
 11 import javax.servlet.http.HttpServletRequest;
 12 import javax.servlet.http.HttpServletResponse;
 13 
 14 public class BaseServlet extends HttpServlet {
 15     private static final long serialVersionUID = 1L;
 16 
 17     public BaseServlet() {
 18     }
 19 
 20     protected void doGet(HttpServletRequest request, HttpServletResponse response)
 21             throws ServletException, IOException {
 22         String action = request.getParameter("action");
 23         if (action != null && !"".equals(action)) {
 24             Class<?> clazz = this.getClass(); // 获取当前执行的servlet的反射对象
 25             Method[] methods = clazz.getDeclaredMethods(); // 获取反射对象的所有方法
 26             for (Method method : methods) {
 27                 if (action.equals(method.getName())) { // 查询action是否有对应的方法
 28                     InvokeMethod(method, request, response); // 调用执行匹配的method
 29                     break;
 30                 }
 31             }
 32         }
 33     }
 34 
 35     /**
 36      * 执行method和封装param
 37      * @param method
 38      * @param request
 39      * @param response
 40      */
 41     private void InvokeMethod(Method method, HttpServletRequest request, HttpServletResponse response) {
 42         try {
 43             Object[] paramIns = packageParam(method, request, response); // 封装method的形参
 44             String invoke = (String) method.invoke(this, paramIns); // 调用对应方法执行,就收返回结果
 45             responseClient(invoke, request, response); // 响应客户端
 46         } catch (InstantiationException e) {
 47             e.printStackTrace();
 48         } catch (IllegalAccessException e) {
 49             e.printStackTrace();
 50         } catch (IllegalArgumentException e) {
 51             e.printStackTrace();
 52         } catch (InvocationTargetException e) {
 53             e.printStackTrace();
 54         }
 55     }
 56 
 57     /**
 58      * 封装method参数
 59      * @param method
 60      * @param request
 61      * @param response
 62      * @return
 63      * @throws InstantiationException
 64      */
 65     private Object[] packageParam(Method method, HttpServletRequest request, HttpServletResponse response) throws InstantiationException {
 66         
 67         Parameter[] parameters = method.getParameters(); // 获取method的所有参数
 68         Object[] paramIns = new Object[parameters.length]; // 创建一个数组,用来保存处理后的参数
 69         
 70         for (int i = 0; i < parameters.length; i++) { // 遍历参数
 71             Class<?> paramObj = parameters[i].getType(); // 获取参数的Class
 72             if ("HttpServletRequest".equals(paramObj.getSimpleName())) { // 处理 HttpServletRequest 参数
 73                 paramIns[i] = request;
 74             } else if ("HttpServletResponse".equals(paramObj.getSimpleName())) { // 处理 HttpServletResponse 参数
 75                 paramIns[i] = response;
 76             } else {
 77                 Object instance = null;
 78                 try {
 79                     instance = paramObj.newInstance(); // 实例化paramObj
 80                 } catch (IllegalAccessException e1) {
 81                     e1.printStackTrace();
 82                 }
 83                 Field[] fields = paramObj.getDeclaredFields(); // 获取paramObj所有的属性
 84                 try {
 85                     for (Field field : fields) { // 遍历属性
 86                         field.setAccessible(true); // 私有属性授权
 87                         String fieldName = field.getName(); // 获取属性名称
 88                         String value = request.getParameter(fieldName); // 根据属性名称从request中获取对应的值
 89                         Object val = null;
 90                         if (value != null && !"".equals(value)) {
 91                             val = changeParamType(value, field.getType()); // 把值类型转变为对应属性的类型
 92                             field.set(instance, val); // 把值赋给paramObj实例的对应属性
 93                         }
 94                     }
 95                 } catch (IllegalAccessException e) {
 96                     e.printStackTrace();
 97                 }
 98                 paramIns[i] = instance; // 保存参数
 99             }
100         }
101         return paramIns;
102     }
103 
104     /**
105      * 表单数据类型转换
106      * @param value
107      * @param type
108      * @return
109      */
110     private Object changeParamType(String value, Class<?> type) {
111         Object val = null;
112         
113         String name = type.getSimpleName(); // 获取类型名称
114         if ("String".equals(name)) {
115             val = value;
116         } else if ("Integer".equals(name)) {
117             val = Integer.parseInt(value);
118         } // 如有其他类型数据,else if 添加即可
119         return val;
120     }
121 
122     /**
123      * 解析执行结果
124      * @param invoke
125      * @param request
126      * @param response
127      */
128     private void responseClient(String invoke, HttpServletRequest request, HttpServletResponse response) {
129         String[] split = invoke.split(":");
130         try {
131             if ("forward".equals(split[0])) {
132                 request.getRequestDispatcher(split[1]).forward(request, response);
133             } else if ("redirect".equals(split[0])) {
134                 response.sendRedirect(split[1]);
135             }
136         } catch (ServletException e) {
137             e.printStackTrace();
138         } catch (IOException e) {
139             e.printStackTrace();
140         }
141     }
142     
143     protected void doPost(HttpServletRequest request, HttpServletResponse response)
144             throws ServletException, IOException {
145         doGet(request, response);
146     }
147 
148 }
BaseServlet.java

4)新建一个class,命名为UserServlet,UserServlet不需要继承HttpServlet,直接继承BaseServlet就可以了,但是要再在web.xml中注册;UserServlet中直接定义方法即可,但是方法名称必须和前端调用的名称保持一致

 1 package com.qf.servlet;
 2 
 3 import java.io.IOException;
 4 
 5 import javax.servlet.http.HttpServletRequest;
 6 
 7 import com.qf.entity.User;
 8 
 9 @SuppressWarnings("all")
10 public class UserServlet extends BaseServlet {
11 
12     public String addUser(User user, HttpServletRequest request) throws IOException {
13         request.setAttribute("user", user);
14         return "forward:test.jsp";
15     }
16 }
UserServlet.java

5)编写一个test.jsp,接收响应

 1 <%@ page language="java" contentType="text/html; charset=UTF-8"
 2     pageEncoding="UTF-8"%>
 3 <%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c"%>
 4 <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
 5 <html>
 6 <head>
 7 <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
 8 <title>Insert title here</title>
 9 </head>
10 <body>
11 <h4>姓名:${user.name}</h4>
12 <h4>密码:${user.password}</h4>
13 <h4>年龄:${user.age}</h4>
14 </body>
15 </html>
test.jsp

6)验证

  a) 启动tomcat,浏览器输入项目部署路径,进入index.jsp,填写数据,提交

  b) test.jsp展示OK,抽取成功

7)第一次写博客,如有不正之处,还请指正,谢谢!

原文地址:https://www.cnblogs.com/brucevon/p/9495303.html