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

   日期:2020-10-05     浏览:183    评论:0    
核心提示:SpringMVC页面向controller层传值的自动映射条件,表单的name值与参数名对应,或使用注解@RequestParam进行对象,或与对象中的属性名对应,并且需要提供setter方法,才能完成参数的赋值,其中是如何进行赋值的过程我们并不知道吗、,也不关心,只知道、如何去使用它就够了,这也就是我们学习效率不高的原因,只知其然,不知其所以然下面是模拟springMVC向入参为对象中映射值的过程,从此不在Servlet中使用request.getParameter;条件:表单name

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

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

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

条件:

  1. 表单name属性的值必须与对象属性名相同
  2. 必须提供属性公共的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;
    }
    @Override
    public 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 { 
	
    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;
            }
            
            Field field = cls.getDeclaredField(paramName);
            //获取参数类型,没有包名,getSimpleName()此方法是去除包名的
            String fieldType 
            =field.getType().getSimpleName();
            
            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 { 
    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { 
        req.setCharacterEncoding("UTF-8");
        //要存储表单数据的对象
        Student stu = new Student();
        try { 
        	//直接调用,传入要存储表单数据的对象,和request
            BeanOperateTools.setValueSimple(stu,req);
        } catch (Exception e){ 
            e.printStackTrace();
        }
        //将封好的数据存入request中,
        req.setAttribute("stu",stu);
        //跳转页面,查看封装的数据是否正确
        req.getRequestDispatcher("show.jsp").forward(req,resp);
    }
    @Override
    protected 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的参数自动映射的条件:

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

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

 
打赏
 本文转载自:网络 
所有权利归属于原作者,如文章来源标示错误或侵犯了您的权利请联系微信13520258486
更多>最近资讯中心
更多>最新资讯中心
0相关评论

推荐图文
推荐资讯中心
点击排行
最新信息
新手指南
采购商服务
供应商服务
交易安全
关注我们
手机网站:
新浪微博:
微信关注:

13520258486

周一至周五 9:00-18:00
(其他时间联系在线客服)

24小时在线客服