Struts2模型驱动核心机制详解
2016-03-11 16:35
281 查看
Struts2采用模型驱动来实现对于表单的多个属性进行封装并通过调用action中的set方法来注入到action中对应的POJO.
首先,Struts2中包括属性注入和域模型注入,属性注入正如我们所熟悉的servlet中对于每个表单提交过来的参数进行request的getParameter方法,
获取每个属性值来注入类中。域模型注入则是上面我们所说的属性封装,下面我们看个例子:
首先定义jsp页面中的表单:
再来看下我们定义的action类:
我么使用servlet来模拟这一封装操作,这里用到了java的反射机制:
LoginServlet类:
BaseServlet:
1)当请求发送到action之前,调用loginServlet类中getModel() 获取要将表单数据封装到哪个实例化的对象中
2)获得到该对象之后,我们可以获得 类类型
3)获得类 类型之后。获得类中的属性request.getParameters获得 表单提交的所有数据名从而获取值
4)如果表单提交的 name值 与 实体类中属性名一致那么我们将获得表单中的数据 封装到us对象当中去
5)最后调用servlet类中的execute执行具体action逻辑
总结:
Struts2中的模型驱动是通过反射机制来实现POJO属性的自动封装和注入的。
首先,Struts2中包括属性注入和域模型注入,属性注入正如我们所熟悉的servlet中对于每个表单提交过来的参数进行request的getParameter方法,
获取每个属性值来注入类中。域模型注入则是上面我们所说的属性封装,下面我们看个例子:
首先定义jsp页面中的表单:
<form action="hello.action" method="post"> 用户名:<input type="text" name="user.userName"/><br/><br/> 密码:<input type="text" name="user.password"/><br/><br/> <input type="submit" value="提交"/> </form>
再来看下我们定义的action类:
import com.opensymphony.xwork2.ModelDriven; import entity.User; public class HelloAction { //定义实体对象属性,接收表单参数:用户名、密码 private User user; public void setUser(User user) { System.out.println("注入对象user..."); this.user = user; } public User getUser() { return this.user; } /** * 在业务方法中输出“Hello,Action.” */ public String execute() { System.out.println("Hello,Action."); // 输出基本类型数据 // 输出域模型方式注入的参数 System.out.println("用户名:" + user.getUserName()); System.out.println("密码:" + user.getPassword()); return "success"; } }我们可以看到,struts2通过ModelDriven类自动将user.userName和user.passWord封装进action中的user对象,然后struts2调用默认的execute方法来执行之后的操作,那么模型驱动是如何完成这一封装机制的呢,我们就通过下面这个例子讲解一下:
我么使用servlet来模拟这一封装操作,这里用到了java的反射机制:
LoginServlet类:
import java.io.IOException; import java.io.PrintWriter; import javax.servlet.ServletException; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import com.pojo.Users; public class LoginServlet extends BaseServlet { //http://www.jikexueyuan.com/course/530.html private Users us = new Users(); public String execute() throws Exception { System.out.println("自动封装数据后的结果:"); System.out.println(us.getUsername()); System.out.println(us.getPassword()); return "/index.jsp"; } public Users getModel() { // TODO Auto-generated method stub return us; } }这里的LoginServlet继承了BaseServlet,并且定义并实例化了pojo:Users,Users包含两个属性:username和password,并且通过getModel方法我们可以返回实例化的属性,我们再来看看BaseServlet
BaseServlet:
import java.io.IOException; import java.io.PrintWriter; import java.lang.reflect.Field; import java.lang.reflect.Method; import java.util.Enumeration; import javax.servlet.ServletException; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; public class BaseServlet extends HttpServlet { public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { doPost(request, response); } public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { try { //在程序运行时 获得当前类的getModel方法对象 Method method = this.getClass().getDeclaredMethod("getModel", null); //通过invoke方法 调用该方法 获得实体类对象 Object ob = method.invoke(this, null); //通过实体类对象获得 类类型 Class cl = ob.getClass(); //通过类类型获得 类中的属性对象数组 Field[] fi = cl.getDeclaredFields(); //通过request获得所有的 表单中提交的name值 Enumeration em = request.getParameterNames(); //循环枚举中的值 while(em.hasMoreElements()){ //获得枚举中的值 就是表单提交的name值 String fieldName = em.nextElement().toString(); System.out.println("从表单中获得的 name值;"+fieldName); //循环类中所有的属性对象 for(int i =0;i<fi.length;i++){ System.out.println("从类中获得的属性:"+fi[i].getName()); //判断 如果类中属性的名字 和 表单中提交的名字一致 if(fieldName.equals(fi[i].getName())){ fi[i].setAccessible(true);//原本对象属性为private,可以被外部赋值 //获取request.getParameter(fieldName) 封装到对象中 fi[i].set(ob, request.getParameter(fieldName)); } } } //调用默认的方法 执行处理 Method me1 = this.getClass().getDeclaredMethod("execute", null); //获得返回的url字符串 Object url = me1.invoke(this, null); //根据返回的字符串 跳转页面 request.getRequestDispatcher(String.valueOf(url)).forward(request, response); } catch (Exception e) { e.printStackTrace(); } } }这里我们模拟了这一数据封装操作,即
1)当请求发送到action之前,调用loginServlet类中getModel() 获取要将表单数据封装到哪个实例化的对象中
2)获得到该对象之后,我们可以获得 类类型
3)获得类 类型之后。获得类中的属性request.getParameters获得 表单提交的所有数据名从而获取值
4)如果表单提交的 name值 与 实体类中属性名一致那么我们将获得表单中的数据 封装到us对象当中去
5)最后调用servlet类中的execute执行具体action逻辑
总结:
Struts2中的模型驱动是通过反射机制来实现POJO属性的自动封装和注入的。
相关文章推荐
- Struts - 标签库
- struts1.0于struts2.0的比较
- Struts2中关于namespace的学习心得
- Struts2----自定义action的学习心得
- HTTP Status 404 - There is no Action mapped for namespace [/] and action name [login!welcome] associ
- struts2
- struts 学习笔记
- struts2框架架构流程
- struts2.0拦截器(实现未登录的用户不能访问系统的页面)(转)
- Struts2 面试题分析
- Struts2+jQuery+JSON实现异步交互
- 软件开发疑惑解答
- ajax ssh 整合
- struts2 @Action给方法注解
- struts2登陆拦截器
- struts2框架原理
- web.xml
- web.xml
- struts2框架原理
- struts2登陆拦截器