反射的应用案例-将表单数据填充到javabean中

反射的应用案例

在之前的servlet里面我们接收表单提交参数都是使用

request.getParameter()

当表单参数较多的话,需要调用多次上面的方法才能获取到表单提交的数据,这样子代码就显得不太整洁了,这里我们来使用反射编写一个自动将表单数据填充到javabean的工具类。

创建一个User的javabean

package com.monkey1024.bean;

public class User {

    private String name;

    private int age;


    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }

}

然后编写一个jsp用来提交表单:

<form action="/addUser" method="post">
    姓名:<input type="text" name="name"><br>
    年龄:<input type="text" name="age"><br>
    <input type="submit" value="提交">
</form>

之后创建一个BeanUtil的工具类,在这个工具类中,我们使用反射获取javabean中的方法,然后根据表单中的name属性找到与之对应的方法,将表单数据填充到javabean中相应的属性上,这里需要保证表单中的name属性和javabean中的属性名一致:

package com.monkey1024.util;

import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;

public class BeanUtil {

    public static void initBean(Object obj, String name, String value) throws InvocationTargetException, IllegalAccessException {
        //把字段名称转化为方法名称 例如:name 转化为setName
        String methodName = "set" + name.toUpperCase().charAt(0) + name.substring(1);
        //拿到类中所有的方法,不包含父类的方法
        Method[] methods = obj.getClass().getDeclaredMethods();
        for (Method method : methods) {

            //获得方法名称
            String objMethodName = method.getName();

            //如果转化过的setName和类中的任意一个方法匹配上了,就调用该方法把value以参数的形式传递给该方法
            if (methodName.equals(objMethodName)) {

                //方法对象中如果是String 类型就要把 value转化为String 对象,如果是int 类型就要把 value转化为 Integer对象
                //拿到方法对象中的参数类型数组从而判断当前参数的类型
                Class[] paramTypes = method.getParameterTypes();

                //拿到第一个参数的类型以字符串的形式返回
                String paramType = paramTypes[0].getSimpleName();

                if ("int".equals(paramType)) {
                    //相当于 obj.setName(param);
                    method.invoke(obj, Integer.parseInt(value.toString()));
                } else if ("String".equals(paramType)) {
                    method.invoke(obj, value.toString());
                } else if ("long".equals(paramType)) {
                    method.invoke(obj, Long.parseLong(value.toString()));
                }

            }
        }
    }
}

在servlet中调用上面的BeanUtil工具类就可以实现自动将表单数据填充到javabean了。

package com.monkey1024.servlet;

import com.monkey1024.bean.User;
import com.monkey1024.util.BeanUtil;

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;
import java.io.PrintWriter;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.Enumeration;
import java.util.Map;

@WebServlet("/addUser")
public class UserServlet extends HttpServlet {
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {

        //获取请求中所有的参数
        Map<String, String[]> parameterMap = request.getParameterMap();
        try {
            //创建要将数据填充的javabean对象
            User user = new User();
            //遍历parameterMap获取请求参数
            for (Map.Entry<String, String[]> entry : parameterMap.entrySet()) {
                //这里不考虑其他情况,只选择String数组0位置上的元素传入
                BeanUtil.initBean(user, entry.getKey(), entry.getValue()[0]);
            }

            System.out.println(user.getName());
            System.out.println(user.getAge());

        } catch (InvocationTargetException e) {
            e.printStackTrace();
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        }


    }





    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        doPost(request, response);
    }
}