java 反射机制-学习笔记(4)
2017-10-30 21:20
555 查看
servlet 自定义反射
如果在jsp 页面直接写 javaBean 标签会显得重复啰嗦,解决这个问题就是要把它单独作为一个组件。先看在servlet 中通过反射接受、设置参数的例子。继续上次的项目添加一个 StudentServlet 类:
package cn.lyx.servlet; import java.io.IOException; import java.lang.reflect.Field; import java.lang.reflect.Method; import java.util.Enumeration; 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 cn.lyx.reflact.Student; @WebServlet(urlPatterns={"/jsp/StudentServlet"}) public class StudentServlet extends HttpServlet{ @Override protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { super.doGet(req, resp); } @Override protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { req.setCharacterEncoding("UTF-8"); Object student = null; try { // 取得Class 对象 Class<?> cls = Class.forName("cn.lyx.reflact.Student"); student = cls.newInstance(); // 实例化对象 // 取得所有输入的参数名称 Enumeration<String> enu = req.getParameterNames(); // 遍历获取输入的参数 while(enu.hasMoreElements()){ String paramName = enu.nextElement(); String paramValue = req.getParameter(paramName); // 通过反射获得指定属性 // 因为输入 的参数名称和对象属性名称一致,可以把属性和输出参数名称一一对应操作。 // 取得属性的类型是为了取得参数的类型,以确定method 方法,和是否转型 Field field = cls.getDeclaredField(paramName); // 获得指定参数 // 首字母大写,比如 name 的set 方法名是 setName(首字母大写) 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(student, paramValue); // 通过反射调用方法 break; case "int": method.invoke(student, Integer.parseInt(paramValue)); break; case "integer": method.invoke(student, Integer.parseInt(paramValue)); break; case "double": method.invoke(student, Double.parseDouble(paramValue)); break; default: break; } } } catch ( Exception e) { e.printStackTrace(); } req.setAttribute("student", student); req.getRequestDispatcher("student_insert_do.jsp").forward(req, resp); } }
可以看到StudentServlet 类中通过反射的方式完成了 Student 的实例化以及设置属性值。
修改 index.jsp ,只是换了请求action 的值,和servlet 中的urlPatterns值对应。 如下:
<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%> <html> <head> <title>首页</title> </head> <body> <% request.setCharacterEncoding("UTF-8"); %> <form action="StudentServlet" method="post"> 姓名:<input type="text" name="name"><br> 年龄:<input type="text" name="age"><br> 成绩:<input type="text" name="score"><br> <input type="submit" value="输入"> <input type="reset" value="重置"> </form> </body> </html>
student_insert_do.jsp 修改比较大,去掉所有javaBean标签,留下简洁的 ${}取值。 修改如下:
<%@ 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> </body> </html>
如之前一样测试,结果正常。
反射组件封装
上面的反射部分直接写在servlet 中,假如有多个servlet那么需要一个个去重复写,不符合可复用的开发原则。那么就需要单独封装在工具类中。新建一个工具类 :
package cn.lyx.util; import java.lang.reflect.Field; import java.lang.reflect.Method; import java.util.Enumeration; import javax.servlet.ServletRequest; /** * 利用反射进行所有请求参数设置, * @author ShayneLee * */ public class BeanOperateTools { /** * * @param obj 传递过来要操作的对象 * @param req 传递输入的参数过来 * @throws Exception */ public static void setValueSimple(Object obj, ServletRequest req) throws Exception{ // 取得Class 对象 Class<?> cls = obj.getClass(); // 这里把之前的那个实例化语句删除。因为传递过来的对象已经被实例化过了,这里就不用重复实例化 // 取得所有输入的参数名称 Enumeration<String> enu = req.getParameterNames(); // 遍历获取输入的参数 while(enu.hasMoreElements()){ String paramName = enu.nextElement(); String paramValue = req.getParameter(paramName); // 因为输入 的参数名称和对象属性名称一致,可以把属性和输出参数名称一一对应操作。 // 取得属性的类型是为了取得参数的类型,以确定method 方法,和是否转型 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; } } } }
这个工具类直接把 servlet 类中的反射部分复制过来。
修改StudentServlet类如下:
package cn.lyx.servlet; import java.io.IOException; 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 cn.lyx.reflact.Student; import cn.lyx.util.BeanOperateTools; @WebServlet(urlPatterns={"/jsp/StudentServlet"}) public class StudentServlet extends HttpServlet{ @Override protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { super.doGet(req, resp); } @Override protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws Servl 9d59 etException, IOException { req.setCharacterEncoding("UTF-8"); Student student = new Student(); // 调用反射工具类 try { BeanOperateTools.setValueSimple(student, req); } catch (Exception e) { // TODO Auto-generated catch block e.printStackTrace(); } req.setAttribute("student", student); req.getRequestDispatcher("student_insert_do.jsp").forward(req, resp); } }
看到这样的 servlet 类,是不是感觉世界清静了很多。
如同之前的测试,一切正常。
参考:魔乐科技-李兴华-java 反射机制
相关文章推荐
- 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 反射机制-学习笔记