zoukankan      html  css  js  c++  java
  • 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)第一次写博客,如有不正之处,还请指正,谢谢!

  • 相关阅读:
    算法:最大回文子串问题
    Python HTTP库requests中文页面乱码解决方案!
    Python:默认参数
    在博客园开通个人博客了
    JQ选择器
    C# 接口
    C# 微信公众平台开发(2) 微信菜单
    C# 微信公众平台开发(1) 服务器配置
    博客园开博第一天!记录生活,扬帆启航!
    JavaScript判断、循环、Map、Set
  • 原文地址:https://www.cnblogs.com/brucevon/p/9495303.html
Copyright © 2011-2022 走看看