首页 > 代码库 > servlet自动获取前端页面提交数据

servlet自动获取前端页面提交数据

servlet自动获取前端页面jsp提交数据

  以下是本人在学习过程中,因前端页面提交参数过多,后台servlet封装实体类过于麻烦而写的一个工具类,应用于jsp/servlet数据提交后,基于MVC+MyBatis进行数据持久化的过程。这里只介绍页面到servlet(controller)提交数据封装对象的过程,MVC+MyBatis访问数据库不在这里介绍。

1.前端页面及代码

  1)前端表单页面构建(用于测试简单构建的页面有点丑陋哦~)

      技术分享

  2)前端jsp页面代码

       这里使用了Ajax异步 get去除缓存方式提交表单。传统方式请自测,本人都已经测试过,在这里不做展示。

     注意:在Ajax提交表单部分使用了jQuery的serialize()序列号函数,初学者可参看jQuery的帮助文档。如不理解,可以在data部分使用“字符串”或json对象的方式进行常规方式提交数据。

 1 <%@ page language="java" contentType="text/html; charset=UTF-8"
 2     pageEncoding="UTF-8"%>
 3 <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
 4 <html>
 5 <head>
 6 <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
 7 <title>Insert title here</title>
 8 <script type="text/javascript" src="http://www.mamicode.com/jquery-1.11.1-min.js"></script>
 9 <script type="text/javascript">
10     $(function(){
11         $("#submitBtn").click(function(){
12             $.ajax({
13                 url:"${pageContext.request.contextPath }/testPage",
14                 data:$("#formId").serialize(), //jQuery中的函数,序列号表格为字符串
15                 type:"get",
16                 cache:false,
17                 success:function(jsonObj){
18                     alert(jsonObj.msg);
19                     $("#formId")[0].reset();//重置表单
20                 }
21             })
22         });
23     })
24         
25 </script>
26 </head>
27 <body>
28     <form id="formId">
29     ID:<input id="id" name="id"><br>
30     姓名:<input id="username" name="username"><br>
31     性别:<input id="sex" name="sex" ><br>
32     年龄:<input id="age" name="age" ><br>
33     价格:<input id="price" name="price"><br>
34     <input type="button" value="http://www.mamicode.com/提交" id="submitBtn">
35     </form>
36 </body>
37 </html>

 

2.实体类

  5个属性and提供set/get方法

 1 package com.domain;
 2 
 3 public class Person {
 4     String username;
 5     String sex;
 6     int age;
 7     Double price;
 8     Long id;
 9     public String getUsername() {
10         return username;
11     }
12     public void setUsername(String username) {
13         this.username = username;
14     }
15     public String getSex() {
16         return sex;
17     }
18     public void setSex(String sex) {
19         this.sex = sex;
20     }
21     public int getAge() {
22         return age;
23     }
24     public void setAge(int age) {
25         this.age = age;
26     }
27     public Double getPrice() {
28         return price;
29     }
30     public void setPrice(Double price) {
31         this.price = price;
32     }
33     public Long getId() {
34         return id;
35     }
36     public void setId(Long id) {
37         this.id = id;
38     }
39 }

 

3.后台Servlet代码

  1)封装实体类对象

  这里只讲前端提交数据输出到控制台,证明数据已经获取并封装到对象中。

     其中,p = (Person) EncapsulationUtil.getJavaBean(Person.class, request); 使用了封装体工具,为本人为偷懒所写,在后面提供源码。后面做详细解释。

  注意:前端提交数据和我们需要保持到数据库的数据不完全时,在servlet拿到封装对象后可手动进行设置,如数据的主键id一般我们采用UUID进行后台生产需要手动set进行设置。

技术分享
 1 package com.controller;
 2 
 3 import java.io.IOException;
 4 import java.util.HashMap;
 5 import java.util.Map;
 6 
 7 import javax.servlet.ServletException;
 8 import javax.servlet.http.HttpServlet;
 9 import javax.servlet.http.HttpServletRequest;
10 import javax.servlet.http.HttpServletResponse;
11 
12 import com.domain.Person;
13 import com.fasterxml.jackson.databind.ObjectMapper;
14 import com.utils.EncapsulationUtil;
15 
16 public class testPage extends HttpServlet {
17 
18     protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
19         //定义数据封装体的对象
20         Person p;
21         //定义用于返回json的数据存放集合
22         Map<String,Object> map = new HashMap<>();
23     
24         try {
25             //获取前端页面表单提交的数据
26             p = (Person) EncapsulationUtil.getJavaBean(Person.class, request);
27             //打印封装体中的数据结果
28                 System.out.println("ID---->"+p.getId()+"<-----");
29                 System.out.println("姓名:---->"+p.getUsername()+"<-----");
30                 System.out.println("年龄:---->"+p.getAge()+"<-----");
31                 System.out.println("性别:"+p.getSex());
32                 System.out.println("价格:"+p.getPrice());
33             map.put("msg", "提交成功");
34                         
35         } catch (Exception e1) {
36             e1.printStackTrace();
37             //当前的提交数据类型和实体类中数据格式不一致时,抛出异常
38             System.err.println("getMessage"+e1.getMessage());
39             //将异常信息保存到集合中,返回到前端
40             map.put("msg", e1.getMessage());
41         }
42         
43         //jackson插件,用于将map集合转化为json字符串
44         ObjectMapper ob = new ObjectMapper();
45         //返回json
46         request.setAttribute("json",ob.writeValueAsString(map) );
47         request.getRequestDispatcher("/json.jsp").forward(request, response);
48         
49         
50     /*    Map<String,Object> conditionMap = EncapsulationUtil.getMap(request);
51         
52         Set ketSet =  conditionMap.keySet();
53         for (Object object : ketSet) {
54             String key = (String) object;
55             System.out.println(conditionMap.get(key));
56         }*/
57     }
58 
59     protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
60         doGet(request, response);
61     }
62 
63 }
View Code

 

  2)封装map集合对象(因在MVC+Mybatis中可能用到map结合,所以提供此方法)

  解释:a.这里不再展示如何使用此工具类封装map集合,实现比较简单。

       b.如想测试,将doGet方法中注释掉的代码放开,上面的代码注释掉即可,同样为数据到控制台。

       c.重点!此工具虽然定义了Map<String,Object> 由于页面通过http协议提交的参数通过request.getParameter()获取后为String类型,实际保存在map对象中的数据为Map<String,String>,如需要在后台获取String类型之外的数据格式,需要单独进行获取后转换类型。下面举一个分页查询中的小例子作为补充。其中利用到了Map即可中key相同时,value会覆盖的特性,以保证我们拿到的map集合对象是数据类型满足要求的。

  以下为分页查询中的例子,页码pageNo, 每页显示记录条数pageSize,跳过的记录数skipNo 应均为Integer类型而不是String类型,所以需要做特殊处理。如下 A 和 B 的对比

  A.传统手动接收参数进行封装(找的其他项目中的代码,只为展示使用方法)

技术分享
 1 protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
 2         //获取页面数据
 3         Integer pageNo=Integer.parseInt(request.getParameter("pageNo")); 
 4         Integer pageSize =Integer.parseInt(request.getParameter("pageSize"));
 5         String  name = request.getParameter("name");
 6         String  owner = request.getParameter("owner");
 7         String  type = request.getParameter("type");
 8         String  state = request.getParameter("state");
 9         String  startDate = request.getParameter("startDate");
10         String  endDate = request.getParameter("endDate");
11         Integer  skipNo = (pageNo-1)*pageSize;
12         
13         //封装数据集合
14         Map<String,Object> conditionMap = new HashMap<>();
15         conditionMap.put("pageNo", pageNo);
16         conditionMap.put("pageSize", pageSize);
17         conditionMap.put("name", name);
18         conditionMap.put("owner", owner);
19         conditionMap.put("type", type);
20         conditionMap.put("state", state);
21         conditionMap.put("startDate", startDate);
22         conditionMap.put("endDate", endDate);
23         conditionMap.put("skipNo", skipNo);
24 }
View Code

  B.封装工具进行接收参数

技术分享
 1 @Override
 2     protected void doGet(HttpServletRequest request, HttpServletResponse response)
 3             throws ServletException, IOException {
 4         //获取页面数据
 5         Integer pageNo = Integer.parseInt(request.getParameter("pageNo"));
 6         Integer pageSize = Integer.parseInt(request.getParameter("pageSize"));
 7         Map<String,Object> conditionMap = EncapsulationUtil.getMap(request);
 8         conditionMap.put("pageSize", pageSize);
 9         conditionMap.put("skipNo", (pageNo-1)*pageSize);
10         
11         //创建Service代理对象
12         TransactionService ts = (TransactionService) ServiceFactory.getServiceProxy(new TransactionServiceImpl());
13         PaginationVO<Transaction> pv = ts.getPaginationVO(conditionMap);
14         //响应json
15         ResponseJSON.out(pv, request, response);
16         
17     }
View Code

 

4.封装体工具类

  1).工具类中已经对前端页面提交数据两端可能存在空白进行了处理,减少页面处理过程

  2). 重点!前端提交表单时,要求URL中name=value&name=value...中name部分(或者说表单中name属性的值)要和实体类中属性字段名保持一致,因为工具中封装原理是调用实体类中的set方法,因此实体类中需要提供标准的set方法。

  3).getJavaBean()方法可能会抛出异常,异常发生在前端提交数据和实体中字段类型不一致。如:实体类中年龄为int/Integer,前端提交时输入了“张三”等非法数据。因此最好在前端做表单验证,以保证数据的合法性。

技术分享
  1 package com.utils;
  2 import java.lang.reflect.Field;
  3 import java.lang.reflect.InvocationTargetException;
  4 import java.lang.reflect.Method;
  5 import java.util.Enumeration;
  6 import java.util.HashMap;
  7 import java.util.Map;
  8 
  9 import javax.servlet.http.HttpServletRequest;
 10 
 11 /**
 12  * 获取请求参数封装对象的工具类
 13  * 
 14  */
 15 public class EncapsulationUtil {
 16     
 17     private static int in;
 18     private static float fl;
 19     private static double d;
 20     private static Integer integ;
 21     private static Double doub;
 22     private static Long lon;
 23     /**
 24      * 获取一个JavaBean,封装有request请求传递的参数
 25      * 
 26      * @param claz
 27      *            封装参数的实体类的Class
 28      * @param request
 29      *            接收数据的HttpServletRequest请求
 30      * @return 封装有请求数据的JavaBean实体类
 31      * @throws 当接收到的参数数据类型和实体类对应属性类型不一致时 抛出
 32      *                异常信息:“数据格式有误!” 
 33      */
 34     public static Object getJavaBean(Class<?> claz, HttpServletRequest request) {
 35         
 36         // 1.获取请求中的参数名称
 37         Enumeration<String> params = request.getParameterNames();
 38 
 39         // 2.声明实体类的对象
 40         Object jBeanObj = null;
 41         
 42 
 43             try {
 44                 jBeanObj = claz.newInstance(); // 初始化实体类对象
 45 
 46                 for (Enumeration<String> e = params; e.hasMoreElements();) {
 47                     // 3.遍历获取某一个参数名(属性)
 48                     String paramName = e.nextElement().toString();
 49                     if("_".equals(paramName)){
 50                         continue;
 51                     }
 52                     String paramValue =http://www.mamicode.com/ request.getParameter(paramName).trim();
 53 
 54                     // 4.构建set方法方法名
 55                     String setMethodName = "set" + paramName.substring(0, 1).toUpperCase() + paramName.substring(1);
 56 
 57                     // 5.获取属性的Field对象
 58                     Field field = claz.getDeclaredField(paramName);
 59                     
 60                     // 6.获取属性的声明类型
 61                     Class<?> fieldType = field.getType();
 62 
 63                     // 7.获取set方法的Method对象 (方法名,参数类型的Class)
 64                     Method setMethodObj = claz.getDeclaredMethod(setMethodName, field.getType());
 65                     setMethodObj.setAccessible(true);
 66                     
 67                     // 8.判断属性类型,调用JavaBean的set方法
 68                     if (Integer.class.equals(fieldType)) {
 69                         
 70                         if("".equals(paramValue)){
 71                             setMethodObj.invoke(jBeanObj,integ);
 72                         }else{
 73                             setMethodObj.invoke(jBeanObj, Integer.valueOf(paramValue));
 74                         }
 75                         
 76                     } else if (Long.class.equals(fieldType)) {
 77                         
 78                         if("".equals(paramValue)){
 79                             setMethodObj.invoke(jBeanObj,lon);
 80                         }else{
 81                             setMethodObj.invoke(jBeanObj, Long.parseLong(paramValue));
 82                         }
 83                         
 84                     } else if (Double.class.equals(fieldType)) {
 85                         
 86                         if("".equals(paramValue)){
 87                             setMethodObj.invoke(jBeanObj,doub);
 88                         }else{
 89                             setMethodObj.invoke(jBeanObj, Double.parseDouble(paramValue));
 90                         }
 91                         
 92                     } else if (String.class.equals(fieldType)){
 93                         
 94                         setMethodObj.invoke(jBeanObj, paramValue);
 95                         
 96                     } else if(int.class.equals(fieldType)){
 97                         
 98                         if("".equals(paramValue)){
 99                             setMethodObj.invoke(jBeanObj,in);
100                         }else{
101                             setMethodObj.invoke(jBeanObj, Integer.parseInt(paramValue));
102                         }
103                     } else if(float.class.equals(fieldType)){
104                         
105                         if("".equals(paramValue)){
106                             setMethodObj.invoke(jBeanObj,fl);
107                         }else{
108                             setMethodObj.invoke(jBeanObj, Float.parseFloat(paramValue));
109                         }
110                         
111                     } else if(double.class.equals(fieldType)){
112                         
113                         if("".equals(paramValue)){
114                             setMethodObj.invoke(jBeanObj,d);
115                         }else{
116                             setMethodObj.invoke(jBeanObj, Double.parseDouble(paramValue));
117                         }
118                     }
119                     
120                 }
121             } catch (IllegalAccessException | IllegalArgumentException | InvocationTargetException | NoSuchMethodException | SecurityException | NoSuchFieldException | InstantiationException e) {
122                 e.printStackTrace();
123                 throw new NumberFormatException("数据格式错误,请核对!");
124             }  
125         
126         // 9.返回封装对象
127         return jBeanObj;
128     }
129 
130     /**
131      * 获取请求数据的Map集合封装体
132      * 
133      * @param request
134      *            接收数据的HttpServletRequest请求
135      * @return 返回封装请求中数据的Map<String ,Object>
136      */
137     public static Map<String, Object> getMap(HttpServletRequest request) {
138         // 0.创建Map集合
139         Map<String, Object> map = new HashMap<String, Object>();
140 
141         // 1.获取请求中的参数名称
142         Enumeration<String> params = request.getParameterNames();
143 
144         for (Enumeration<String> e = params; e.hasMoreElements();) {
145             // 2.遍历获取某一个参数名称
146             String paramName = e.nextElement().toString();
147             // 3.获取参数值
148             String paramValue =http://www.mamicode.com/ request.getParameter(paramName).trim();
149             // 4.封装数据
150             map.put(paramName, paramValue);
151         }
152         // 5.返回封装体集合
153         return map;
154     }
155 
156     private EncapsulationUtil() {
157     }
158 }
View Code

 

5.工具目录图

  其中ajax部分json.jsp如下: 

<%@ page language="java" contentType="text/json; charset=UTF-8"
    pageEncoding="UTF-8"%>
${json}

   工具目录图(测试一切从简,请勿追问包结构不完整之类问题)

    技术分享

 

6.效果展示

  将工程发布到Tomcat中,进行访问http://localhost:8080/reflect/test.jsp

  1)前端提交正常数据

    前端页面

    技术分享

    点击提交后,后台控制台输出及前端显示

    技术分享

  2)前端提交非法数据时(未做表单验证)

    年龄应为int类型,底层使用了Integer.valueOf(paramValue)因此会发生数据格式换行异常。这是需要注意的地方!!特殊地方最好做表单验证,这是测试demo就不再丰富。

    技术分享

 

 说明:本例中工具类纯属个人学习过程中在不使用Spring等框架的前提下 为偷懒所写,如使用生产环境发生问题,概不负责!

转载请注明出处,谢谢!^.^

 

    

servlet自动获取前端页面提交数据