java 反射机制-学习笔记(6)
2017-11-08 22:46
651 查看
通过反射实例化对象
本节介绍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= b502 "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 通过反射的方式把公共代码部分组合在一起,大大减少了代码冗余部分,遵循高内聚,低耦合,可复用原则 提高了开发效率。相关文章推荐
- java基础学习笔记——反射机制
- 《Spring 3.x 企业应用开发实战》学习笔记 第三章 IoC容器概述 3.2 相关Java基础知识 类装载器 反射机制
- 黑马程序员——JAVA学习笔记——反射机制(下)
- Effective Java 学习笔记(第53条:接口优先于反射机制)
- Java学习笔记09--反射机制
- JAVA的反射机制学习笔记(一)
- java学习笔记09--反射机制
- 黑马程序员 java学习笔记 Day11:反射机制详解
- JAVA的反射机制学习笔记(二)
- 黑马程序员学习笔记之八(Java 反射机制)
- java学习笔记09--反射机制
- java学习笔记---类型信息(type information)、反射机制与动态代理
- java学习笔记09--反射机制
- Android(java)学习笔记106-1:类的加载器(反射机制)
- 15. JAVA 反射机制 Part 1(Class类、反射、反射机制) ----- 学习笔记
- java学习笔记-反射机制
- 《Spring 3.x 企业应用开发实战》学习笔记 第三章 IoC容器概述 3.2 相关Java基础知识 类装载器 反射机制
- 黑马程序员——JAVA学习笔记——反射机制(上)
- JAVA的反射机制学习笔记(二)
- Java 反射机制-学习笔记