java 反射机制-学习笔记(6)

来源:互联网 发布:并发编程研究内容 编辑:程序博客网 时间:2024/06/07 20:39

通过反射实例化对象


本节介绍JSP 提交的参数名称带有不同的实例名称,通过反射机制对不同的对象类型进行实例化。
项目结构:
项目结构图

代码

先建立两个简单javaBean 对象:
学生类

package cn.lyx.reflact;import java.io.Serializable;/** * @author ShayneLee */public class Student implements Serializable{    private String name;    private Integer age;    private Double score;    public String getName() {        return name;    }    public void setName(String name) {        this.name = name;    }    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 + "]";    }}

老师类

package cn.lyx.reflact;/** * Created by ShayneLee on 2017/11/8 */public class Teacher {    private String work;    private Double wages;    public void setWork(String work) {        this.work = work;    }    public String getWork() {        return work;    }    public void setWages(Double wages) {        this.wages = wages;    }    public Double getWages() {        return wages;    }    @Override    public String toString() {        return work +  "," +wages;    }}

然后建一个公共servlet 父类,这个类主要是统一处理反射调用,转发等。

package cn.lyx.servlet;import cn.lyx.util.BeanOperateTools;import javax.servlet.ServletException;import javax.servlet.http.HttpServlet;import javax.servlet.http.HttpServletRequest;import javax.servlet.http.HttpServletResponse;import java.io.IOException;import java.lang.reflect.Method;import java.util.Enumeration;/** * 这是Servlet 的父类,统一在此类做请求响应分发,跳转。 * @author ShayneLee */public abstract class DispatcherServlet extends HttpServlet{    private HttpServletRequest request;    private HttpServletResponse response;    // 统一处理request,response    public HttpServletRequest getRequest() {        return request;    }    public HttpServletResponse getResponse() {        return response;    }    @Override    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {        this.doPost(req, resp);    }    @Override    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {        this.request = req;        this.response = resp;        String url = "/jsp/default.jsp"; // 默认跳转路径        Object obj = this.getBean(req);  // 反射调用要操作的对象实例名称        String uri = req.getRequestURI();        String status = uri.substring(uri.lastIndexOf("/")+1);        Class<?> cls = this.getClass();// 这里一定用 this.getClass 而不是DispatcherServlet.class,否则取不到方法        try {            Method method = cls.getMethod(status);            // 反射调用子类状态操作方法  如 insert()            url = method.invoke(this).toString();        } catch (Exception e) {            e.printStackTrace();        }        String paramObj = obj.getClass().getSimpleName().toLowerCase();        req.setAttribute(paramObj, obj);        req.getRequestDispatcher(url).forward(req, resp);    }    /**     * 反射调用取得要操作的对象     * @param request     * @return     */    public Object getBean(HttpServletRequest request){        String fullParamName = null;        Enumeration<String> enu = request.getParameterNames();        Object resultObj = null;        while (enu.hasMoreElements()) {            fullParamName = enu.nextElement();            // 获取参数参数名称. 号前面的名称,  如获取student.name  的student            if (fullParamName.contains(".")){                String[] temp = fullParamName.split("\\.");                String objName = temp[0];                String firstUp = objName.substring(0,1).toUpperCase()                        .concat(objName.substring(1).toLowerCase());                Method met = null;                try {                    // 这里一定用 this.getClass 而不是DispatcherServlet.class,否则取不到方法                    // 调用子类servlet 的获取对象实例方法  如 getStudent                    met = this.getClass().getMethod("get" + firstUp);                    resultObj = met.invoke(this);                    // 设置属性值  如 设置属性 name 的值                    String paramName = temp[1];                    String paramValue = request.getParameter(fullParamName);                    BeanOperateTools.setValueSimple(resultObj, paramName, paramValue);                } catch (Exception e) {                    e.printStackTrace();                }            }        }        return resultObj;    }}

两个子类servlet :

package cn.lyx.servlet;import javax.servlet.annotation.WebServlet;import cn.lyx.reflact.Student;@WebServlet(urlPatterns={"/jsp/studentServlet/*"})public class StudentServlet extends DispatcherServlet{    private static Student student = null;    /**     * 单例模式     * @return     */    public static Student getStudent() {        if (student == null){            student = new Student();        }        return student;    }    public String insert() {        System.out.println("学生-添加成功");        return "/jsp/insert_do.jsp";    }}

TeacerServlet:

package cn.lyx.servlet;import cn.lyx.reflact.Teacher;import javax.servlet.annotation.WebServlet;@WebServlet(urlPatterns={"/jsp/teacherServlet/*"})public class TeacherServlet extends DispatcherServlet{    private static Teacher teacher = null;    /**     * 单例模式     * @return     */    public static Teacher getTeacher() {        if (teacher == null) {            teacher = new Teacher();        }        return teacher;    }    public String insert() {        System.out.println("老师-添加成功");        return "/jsp/insert_do.jsp";    }}

一个设置属性工具类

package cn.lyx.util;import java.lang.reflect.Field;import java.lang.reflect.Method;/** * 利用反射进行属性参数设置, * @author ShayneLee * */public class BeanOperateTools {    /**     * @author ShayneLee     * @param obj 要实例化的对象     * @param paramValue 传递输入的参数过来     * @throws Exception     */    public static void setValueSimple(Object obj, String paramName, String paramValue)            throws Exception{        // 取得Class 对象        Class<?> cls = obj.getClass();        Field field = cls.getDeclaredField(paramName);  // 为了获得指定参数类型        // 首字母大写        String firstUp = paramName.substring(0,1).toUpperCase()                .concat(paramName.substring(1).toLowerCase());        // 取得set操作方法,满足反射调用        Method method = cls.getMethod("set" + firstUp, field.getType());        // 根据类型进行数据的装换,同时调用setter 设置数据        String fiedlType = field.getType().getSimpleName().toLowerCase();        switch (fiedlType) {            case "string":                method.invoke(obj, paramValue);                break;            case "int":                method.invoke(obj, Integer.parseInt(paramValue));                break;            case "integer":                method.invoke(obj, Integer.parseInt(paramValue));                break;            case "double":                method.invoke(obj, Double.parseDouble(paramValue));                break;            default:                break;        }    }}

JSP 页面部分
学生添加的页面:

<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%><html><head><title>首页</title></head><body>    <%        request.setCharacterEncoding("UTF-8");    %>    <form action="studentServlet/insert" method="post">        学生姓名:<input type="text" name="student.name"><br>        学生年龄:<input type="text" name="student.age"><br>        学生成绩:<input type="text" name="student.score"><br>        <input type="submit" value="输入">        <input type="reset"  value="重置">    </form></body></html>

老师添加jsp:

<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%><html><head><title>首页</title></head><body>    <%        request.setCharacterEncoding("UTF-8");    %>    <form action="teacherServlet/insert" method="post">        老师职业:<input type="text" name="teacher.work"><br>        老师工资:<input type="text" name="teacher.wages"><br>        <input type="submit" value="输入">        <input type="reset"  value="重置">    </form></body></html>

公共结果jsp:

<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%><% request.setCharacterEncoding("UTF-8"); %><html><head><title>Java Bean 操作</title></head><body>    <h5>学生姓名 : ${student.name}</h5>    <h5>学生年龄 : ${student.age}</h5>    <h5>学生成绩 : ${student.score}</h5>    <h5>老师职业 : ${teacher.work}</h5>    <h5>老师工资 : ${teacher.wages}</h5></body></html>

测试

添加学生信息:
学生信息输入
结果:
学生信息结果

老师信息添加:
老师信息添加
结果:
老师信息添加成功

总结

本例主要是测试通过反射实例化不同的对象。做法是通过请求的参数名带上不同的实例名称, servlet 接收到请求的参数信息,通过反射调用对应的实例对象进行属性赋值操作。可见Servlet 通过反射的方式把公共代码部分组合在一起,大大减少了代码冗余部分,遵循高内聚,低耦合,可复用原则 提高了开发效率。

原创粉丝点击