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

通过反射实例化对象


本节介绍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 通过反射的方式把公共代码部分组合在一起,大大减少了代码冗余部分,遵循高内聚,低耦合,可复用原则 提高了开发效率。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值