菲洛嘉青春动能素135HA FILLMED® NCTF 135HA LED指示灯的常见故障分析 智微智能 Elkhartlake K075终端,零售产业新选择 天空蓝拓客管理系统详细介绍版 muso公链项目 天使计划 是什么?[秘] 独家揭秘最前沿的家装“黑科技”——掌赋 天博体育欧洲杯特辑,东道主法兰西的失意2016 亚马逊的送货侦察员 学习听起来像挡泥板 Google Comics Factory使ML变得容易 笑着说-男性或女性 Amazon Rekognition中更好的人脸检测 关于Spaun的真相-大脑模拟 两个聊天机器人彼此聊天-有趣又怪异 GANPaint:将AI用于艺术 WCF和WF给予社区 从耳朵到脸 所有神经网络的深层缺陷 蠕虫在尾巴上平衡杆子 Kickstarter上的OpenCV AI套件 TensorFlow-Google的开源AI和计算引擎 众包取代新闻工作者 Google的DeepMind学会玩街机游戏 哑机器人V智能机器人 .NET与.NET 5融为一体 Google的深度学习-语音识别 LInQer将.NET LINQ移植到Javascript 机器人TED演讲-新的图灵测试? GAN的发明者加入苹果 您的智能手机会监视您键入的内容 人工智能帮助改善国际象棋 Zalando Flair NLP库已更新 TensorFlow 1.5包含移动版本 AlphaGo输了一场比赛-比分3-1 虚拟机器学习峰会 Microsoft开源AI调试工具 SharePoint走向移动 F#4.0发出文化变革的信号 克里斯蒂拍卖AI艺术品 人工智能如何区分 Facebook在蒙特利尔的新AI实验室 Mozilla想要您的声音 微软使用极深的神经网络赢得ImageNet 建立AI合作伙伴关系 .NET Core 3-Microsoft几乎回到了起点 神经网络-更好的销售商? Google使用AI查找您的住所 虹膜-适用于Android的Siri证明苹果没有优势 TensorFlow 2提供更快的模型训练 深度学习研究人员将为Google工作
您的位置:首页 >运维 >

你还在使用getParameter吗?使用反射自定义一个简易的类似与Spring MVC的参数自动映射

SpringMVC页面向controller层传值的自动映射条件,

表单的name值与参数名对应,或使用注解@RequestParam进行对象,或与对象中的属性名对应,并且需要提供setter方法,才能完成参数的赋值,其中是如何进行赋值的过程我们并不知道吗、,也不关心,只知道、如何去使用它就够了,这也就是我们学习效率不高的原因,只知其然,不知其所以然

下面是模拟springMVC向入参为对象中映射值的过程,从此不在Servlet中使用request.getParameter;

条件

表单name属性的值必须与对象属性名相同必须提供属性公共的setter方法

在学习的过程中我们要常保持疑问,带着问题去学习,如果你连疑问都没有,那你自然就不知道你想要的答案是什么,没有想要的答案,也就没有学习的价值,先声明你的疑问,再去学习, 疑问:就是为什么需要这两个条件成立

准备代码:一个实体类,一个表单,一个servlet,

package com.entity;import java.util.Date;/***实体类,将参数值保存在此对象中*/public class Student {private String name;private Integer age;private Double score;private Date birthDay;public Date getBirthDay() {return birthDay;}public void setBirthDay(Date birthDay) {this.birthDay = birthDay;}public Student() {System.out.println("Student的无参构造");}public String getName() {return name;}public void setName(String name) {this.name = name;System.out.println("setName--------》");}public Integer getAge() {return age;}public void setAge(Integer age) {this.age = age;}public Double getScore() {return score;}public void setScore(Double score) {this.score = score;}@Overridepublic String toString() {return "Student{" +"name='" + name + '\'' +", age=" + age +", score=" + score +", birthDay=" + birthDay +'}';}}

表单 ,注:此处使用的是jsp,name值都与实体类中的属性名对应

<%@ page contentType="text/html;charset=UTF-8" language="java" %><html><head><title>$Title$</title></head><body><form action="studentServlet" method="post">name: <input type="text" name="name"><br>age:<input type="text" name="age"><br>score:<input type="text" name="score"><br>birthDay: <input type="text" name="birthDay"><br><input type="submit" value="提交"><br></form></body></html>

在参数自动映射中,我们也只能在Servlet中进行做文章了,为了代码的重用性,我将参数自动映射功能,封装成一个方法,想要使用只需要将此类拷贝即可,方法的具体内容:

package com.utils;import javax.servlet.http.HttpServletRequest;import java.lang.reflect.Field;import java.lang.reflect.Method;import java.text.SimpleDateFormat;import java.util.Enumeration;public class BeanOperateTools {/** * 该方法是由Servlet调用 * 具体实现的参数封装方法 * @param obj 要将表单值封装至的对象 * @param req request对象,包含我们表单请求来的数据 * @throws Exception 可能抛出的异常 */public static void setValueSimple(Object obj, HttpServletRequest req) throws Exception {//得到实体类的类信息Class<?> cls = obj.getClass();//获取所有的参数名称Enumeration<String> enu = req.getParameterNames();//遍历参数名称while (enu.hasMoreElements()){ //获取参数名称String paramName = enu.nextElement();//获取对应的参数名称的值String paramValue = req.getParameter(paramName);//进行判断当前文本框是否填写值,没有值就跳过此属性值的封装if("".equals(paramValue) || null==paramValue){continue;}/*根据表单的name值类取得对应的属性,这就是为什么需要我们表单的name值要与实体类的属性名对应的原因,我们可以根据这个属性的类型,来确定setter方法的参数类型,并确定是否需要进行类型装换*/Field field = cls.getDeclaredField(paramName);//获取参数类型,没有包名,getSimpleName()此方法是去除包名的String fieldType =field.getType().getSimpleName();/*获取指定的操作方法,以满足反射的调用使用字符串set+属性名的方式,并把属性的首字母大写,正好对应我们属相的setter方法,参数类型就是上面的field*/Method method = cls.getMethod("set"+initcap(paramName), field.getType());//此处进行判断是否需要进行类型的转换if("String".equals(fieldType)){ //执行具体set方法,并传入具体值method.invoke(obj, paramValue);}else if("Integer".equals(fieldType) || "int".equals(fieldType)){method.invoke(obj,Integer.parseInt(paramValue));}else if("Double".equals(fieldType) || "double".equals(fieldType)){method.invoke(obj,Double.parseDouble(paramValue));}else if("Date".equals(fieldType)){method.invoke(obj,new SimpleDateFormat("yyyy-MM-dd").parse(paramValue));}}}//将属性名的首字母大写private static String initcap(String value){return value.substring(0,1).toUpperCase().concat(value.substring(1));}}

参数封装方法已完成,只需要在Servlet中调用即可

package com.servlet;import com.entity.Student;import com.utils.BeanOperateTools;import javax.servlet.ServletException;import javax.servlet.annotation.WebServlet;import javax.servlet.http.HttpServlet;import javax.servlet.http.HttpServletRequest;import javax.servlet.http.HttpServletResponse;import java.io.IOException;@WebServlet(name = "StudentServlet", urlPatterns = {"/studentServlet"})public class StudentServlet extends HttpServlet {@Overrideprotected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {req.setCharacterEncoding("UTF-8");//要存储表单数据的对象Student stu = new Student();try {//直接调用,传入要存储表单数据的对象,和requestBeanOperateTools.setValueSimple(stu,req);} catch (Exception e){e.printStackTrace();}//将封好的数据存入request中,req.setAttribute("stu",stu);//跳转页面,查看封装的数据是否正确req.getRequestDispatcher("show.jsp").forward(req,resp);}@Overrideprotected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {this.doPost(req, resp);}}

show.jsp

<%@ page contentType="text/html;charset=UTF-8" language="java" %><html><head><title>Title</title></head><body>${stu}</body></html>

写完这些我们在看一下springMVC的参数自动映射的条件:

表单name属性的值必须与对象属性名相同必须提供属性公共的setter方法 现在知道为什么了吗!

参数自动映射的具体过程,大致就这些,不知道你看明白了吗,当然,我们所写的与springMVC的相比,那就是,小巫見大巫、木棍挑战坦克,重申:此文章,只是让我们能够了解springMVC在进行参数封装的过程,对框架能够有一个更加深层的认知

郑重声明:本文版权归原作者所有,转载文章仅为传播更多信息之目的,如作者信息标记有误,请第一时间联系我们修改或删除,多谢。