孙殿英先盗的谁的墓:action接收请求复合类型参数(反射机机制原理)

来源:百度文库 编辑:中财网 时间:2024/07/08 17:23:49

action接收请求参数

接受请求参数的原理 
在struts2中没有actionForm ,jsp中的表单元素可以在action中定义同名的名称来接受请求参数 然后生成set方法. 
内部机制:struts2的拦截器,会根据页面提交到action中的参数,用反射技术在action类中寻找同名的属性,然后调用action的set方法注入属性值 。
此外,如果在action中的属性太多,可以包装成一个对象 ,用法参考下面的代码 
原理解析:根据表单元素的名称,person.**去寻找action类中定义的person属性,如果person为空, 则用反射机制new出person对象 ,然后注入person的属性值 ,也因此person类必须要有默认的构造函数 。

一、采用基本类型接收请求参数(get/post)
在Action类中定义与请求参数同名的属性,struts2便能接收自动接收请求参数并赋给同名属性。

action的代码:

Java代码

  1. public class ParamAction {  
  2.   
  3.     private Integer id;  
  4.     private String name;  
  5.       
  6.     public String execute(){  
  7.         return "success";  
  8.     }  
  9.       
  10.     public void setId(Integer id) { //通过反射技术调用与请求参数同名的属性的setter方法来获取请求参数值  
  11.         this.id = id;  
  12.     }  
  13.       
  14. }  

public class ParamAction {

 

private Integer id;

private String name;

public String execute(){

  return "success";

}

public void setId(Integer id) { //通过反射技术调用与请求参数同名的属性的setter方法来获取请求参数值

  this.id = id;

}

}

 配置文件:

Xml代码

  1.   
  2.       
  3.     /WEB-INF/jsp/result.jsp  
  4.       
  5.   

 

  /WEB-INF/jsp/result.jsp

 

 form页面,此页面直接保存在根目录下:

Java代码

  1.   
  2. /demo/param.action" method="post">  
  3.     id:  
  4.     name:  
  5.       
  6.   
  7.   

/demo/param.action"method="post">

id:

name:

 在id与name中分别填写信息后,如:123, testParam,点击提交按钮,在result.jsp页面中就会看到相应的值。

result.jsp页面如下所示:

Java代码

  1. <%@ taglib uri="/struts-tags" prefix="s"%>  
  2.   
  3.   
  4. id:${id}  
  5. name:  
  6.   

<%@ taglib uri="/struts-tags"prefix="s"%>

 

id:${id}

name:

测试的页面输出结果为:id:123     name:testParam

 

 二、采用复合类型接收请求参数

action代码如下所示:

Java代码

  1. public class TestAction {  
  2.   
  3.     private Person person;  
  4.   
  5.     public Person getPerson() {  
  6.         return person;  
  7.     }  
  8.   
  9.     public void setPerson(Person person) {  
  10.         this.person = person;  
  11.     }  
  12.       
  13.     public String execute(){  
  14.         return "success";  
  15.     }  
  16.   
  17. }  

public class TestAction {

 

private Person person;

 

public Person getPerson() {

  return person;

}

 

public void setPerson(Person person) {

  this.person = person;

}

public String execute(){

  return "success";

}

 

}

 Person类的代码如下所示:

Java代码

  1. public class Person {  
  2.     private Integer id;  
  3.     private String name;  
  4.        //setter和getter方法  
  5. }  

public class Person {

private Integer id;

private String name;

       //setter和getter方法

}

 配置文件如下:

Xml代码

  1.       
  2.           
  3.         /WEB-INF/jsp/result.jsp  
  4.           
  5.       

 

  /WEB-INF/jsp/result.jsp

 

 from页面的代码如下:

Java代码

  1.   
  2. /demo/test.action" method="post">  
  3.     person.id:  
  4.     person.name:  
  5.       
  6.   
  7.   

/demo/test.action"method="post">

person.id:

person.name:

 在person.id与person.name中分别填写信息后,如:123, testParam,点击提交按钮,在result.jsp页面中就会看到相应的值。Person.id:123    Person.name:testParam

result.jsp中的代码如下所示:

Java代码

  1. <%@ taglib uri="/struts-tags" prefix="s"%>  
  2.   
  3. Person.id:${person.id}  
  4. Person.name:  
  5.   

<%@ tagliburi="/struts-tags" prefix="s"%>

Person.id:${person.id}

Person.name:

  说明:struts2首先通过反射技术调用Person类的默认构造器创建Person对象,然后通过反射技术调用Person类中与请求参数同名的属性的setter方法来获取请求参数值。在这里需要注意的一点是:Person类中一定要有默认的构造器。

采用复合类型接收请求参数的好处,可以减少action中的setter和getter方法,同时可以把相应的属性组合成一个类,这样使代码更好清晰,代码有更好的结构。

 

注意: 在struts2.1.6版本中存在一个bug,即配置了struts.i18n.encoding常量也不能解决接收到的中文请求参数为乱码(以 post方式提交)的问题,原因是此版本在获取请求参数后才调用了HttpServletRequest的setCharacterEncoding() 方法进行编码设置,导致应用使用的就是乱码请求参数。此bug在struts2.1.8中已经解决,并且解决了2.1.6中存在的其它bug,如果你使用 的是struts2.1.6,解决此bug的方法是配置一个filter,把这个Filter放置在Struts2的Filter之前,并在 doFilter方法中增加如下代码:

Java代码

  1. public void doFilter(...){  
  2.     HttpServletRequest req = (HttpServletRequest) request;  
  3.     req.setCharacterEncoding("UTF-8");//应该根据你使用的编码替换UTF-8  
  4.     filterChain.doFilter(request,response);  
  5. }  

@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@

 

在Struts2.0里面有一个非常牛*的功能就是支持更高级的POJO访问

登陆页面login.jsp:
<%@ page language="java" contentType="text/html;charset=utf-8"%>
<%@ taglib prefix="s" uri="/struts-tags" %>



Insert title here



   
   
   




新增实体类User.java:
package tutorial;
public class User {
    private String userName;
    private String password;

//必须要有一个默认的构造器

Public User(){

}
     public String getPassword() {
       return password;
    }
    public void setPassword(String password) {
       this.password = password;
    }
    public String getUserName() {
       return userName;
    }

    public voidsetUserName(String userName) {
       this.userName = userName;
    }
}

请求处理LoginAction.java:
package tutorial;
import com.opensymphony.xwork2.ActionSupport;
public class LoginAction extends ActionSupport {
    private String msg="显示默认消息";
    private User user;
    public User getUser() {
       return user;
    }
    public void setUser(User user) {
       this.user = user;
    }
    public String getMsg() {
       return msg;
    }
    public String execute(){
      if("xiaozhu".equals(user.getUserName())&&"111111".equals(user.getPassword()))
       msg="welcome,"+user.getUserName();
    else
        msg="用户名或密码错误";
    return this.SUCCESS;//
    }
}

响应页面HelloWorld.jsp:
<%@ page language="java" contentType="text/html;charset=utf-8"%>
<%@ taglib prefix="s" uri="/struts-tags" %>


   
        Hello
   
   
       


   

新建了一个User实体类,用于封装从表单中接收的数据,而在action中就不用设置相应的属性和方法了,并且这样做能够让我们的软件层次感更加明显,系统结构也更加清晰。以User为例,描述一下采用这种方式的关键步骤:

1. 在action中定义一个User类型的对象:User user; 
2. 表单中各个控件的name属性要采取如下命名规则:对象名.属性名,注意对象名必须与action中定义的一样,属性名也必须和该对象的属性一一对应。如上例中的user.userName和user.password。

注意:

public User getUser() {
       return user;
}
/Action中的这个get方法必须,否则会出现丢值的现象;set方法就更不用说了,必须的。

上述原理解释:

1. 前面讲的自定义类型转换器是基于 OGNL 的 DefaultTypeConverter 类并实现 convertValue() 方法,两个转换方向的逻辑都写在这一个方法中。而Struts 2 为我们提供了一个 DefaultTypeConverter 的抽象子类 StrutsTypeConverter 来继承,并实现其中两个抽象方法convertFromString()和 convertToString(),这要简单易懂。对比Struts 1 的转换器是要实现org.apache.commons.beanutils.Converter接口,以及它的 convert() 方法的。

2. 注意,上面的 convertFromString() 的第二个参数是一个字符串数组,所以可为请求的数组(如请求串为 ?u=1&u=2&u=3)定义转换器,Action 中相应的属性就应为数组或 List,这一方法的返回值也该为相应的类型(数组或List,要通过第三个参数toClass 来判断是返回数组还是 List 了)。

3. 字符串(如 "user,pass") 转换成 Action 中的复合属性(如User user) 前面是自定了类型转换器。除此之外,还可以 Struts 2 内置的OGNL 表达式,更简单的转换,不用写转换器。例如,你的 Action 有属性 User user,只要在 jsp 页面的输入框命名为 user.name 和user.pass 即可: 
        或用标签: 
        或用标签: