打开APP
userphoto
未登录

开通VIP,畅享免费电子书等14项超值服

开通VIP
action接收请求复合类型参数(反射机机制原理)

action接收请求参数

接受请求参数的原理 
struts2中没有actionForm ,jsp中的表单元素可以在action中定义同名的名称来接受请求参数 然后生成set方法
内部机制:struts2的拦截器,会根据页面提交到action中的参数,用反射技术在action类中寻找同名的属性,然后调用actionset方法注入属性值 
此外,如果在action中的属性太多,可以包装成一个对象 ,用法参考下面的代码 
原理解析:根据表单元素的名称,person.**去寻找action类中定义的person属性,如果person为空, 则用反射机制newperson对象 ,然后注入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. <package name="myDemo" namespace="/demo" extends="struts-default">  
  2.     <action name="param" class="demo.action.ParamAction">  
  3.     <result>/WEB-INF/jsp/result.jsp</result>  
  4.     </action>  
  5. </package>  

<package name="myDemo" namespace="/demo"extends="struts-default">

  <action name="param"class="demo.action.ParamAction">

  <result>/WEB-INF/jsp/result.jsp</result>

  </action>

</package>

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

Java代码

  1. <body>  
  2. <form action="<%=request.getContextPath() %>/demo/param.action" method="post">  
  3.     id:<input type="text" name="id"></input>  
  4.     name:<input type="text" name="name"></input>  
  5.     <input type="submit" name="submit" value="提交"></input>  
  6. </form>  
  7. </body>  

<body>

<formaction="<%=request.getContextPath() %>/demo/param.action"method="post">

id:<input type="text"name="id"></input>

name:<input type="text"name="name"></input>

<input type="submit" name="submit"value="提交"></input>

</form>

</body>

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

result.jsp页面如下所示:

Java代码

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

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

 

<body>

id:${id}

name:<s:propertyvalue="name" />

</body>

测试的页面输出结果为: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.        //settergetter方法  
  5. }  

public class Person {

private Integer id;

private String name;

       //settergetter方法

}

 配置文件如下:

Xml代码

  1. <package name="myDemo" namespace="/demo" extends="struts-default">      
  2.         <action name="test" class="demo.action.TestAction">  
  3.         <result>/WEB-INF/jsp/result.jsp</result>  
  4.         </action>  
  5.     </package>  

<packagename="myDemo" namespace="/demo" extends="struts-default">

  <action name="test"class="demo.action.TestAction">

  <result>/WEB-INF/jsp/result.jsp</result>

  </action>

</package>

 from页面的代码如下:

Java代码

  1. <body>  
  2. <form action="<%=request.getContextPath() %>/demo/test.action" method="post">  
  3.     person.id:<input type="text" name="person.id"></input>  
  4.     person.name:<input type="text" name="person.name"></input>  
  5.     <input type="submit" name="submit" value="提交"></input>  
  6. </form>  
  7. </body>  

<body>

<formaction="<%=request.getContextPath() %>/demo/test.action"method="post">

person.id:<input type="text"name="person.id"></input>

person.name:<input type="text"name="person.name"></input>

<input type="submit" name="submit"value="提交"></input>

</form>

</body>

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

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

Java代码

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

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

<body>

Person.id:${person.id}

Person.name:<s:propertyvalue="person.name" />

</body>

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

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

 

注意:struts2.1.6版本中存在一个bug,即配置了struts.i18n.encoding常量也不能解决接收到的中文请求参数为乱码(以 post方式提交)的问题,原因是此版本在获取请求参数后才调用了HttpServletRequestsetCharacterEncoding() 方法进行编码设置,导致应用使用的就是乱码请求参数。此bugstruts2.1.8中已经解决,并且解决了2.1.6中存在的其它bug,如果你使用 的是struts2.1.6,解决此bug的方法是配置一个filter,把这个Filter放置在Struts2Filter之前,并在 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" %>
<!DOCTYPE html PUBLIC "-//W 3C//DTD HTML 4.01 Transitional//EN" "">
<html>
<head>
<title>Insert title here</title>
</head>
<body>
<s:form action="/test/loginAction.action"method="post">
    <s:textfield name="user.userName" label="
用户名"/>
    <s:password name="user.password" label="
密码"/>
    <s:submit/>
</s:form>
</body>
</html>

新增实体类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" %>
<!DOCTYPE html PUBLIC "-//W 3C//DTD HTML 4.01 Transitional//EN" "">
<html>
    <head>
        <title>Hello</title>
    </head>
    <body>
        <h3><s:propertyvalue="msg"/></h3>
    </body>
</html>

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

1. 在action中定义一个User类型的对象:User user 
2
. 表单中各个控件的name属性要采取如下命名规则:对象名.属性名,注意对象名必须与action中定义的一样,属性名也必须和该对象的属性一一对应。如上例中的user.userNameuser.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 即可: 
        <input type="text"name="user.name"/>
或用标签:<s:textfieldname="user.name" label="用户名"/> 
        <input type="text"name="user.pass"/>
或用标签:<s:textfieldname="user.pass" label="密 码"/>

 

本站仅提供存储服务,所有内容均由用户发布,如发现有害或侵权内容,请点击举报
打开APP,阅读全文并永久保存 查看更多类似文章
猜你喜欢
类似文章
【热】打开小程序,算一算2024你的财运
struts2之请求参数接收
struts2中action实现Preparable接口
基于Struts的AJAX
第一次接触struts2.......
2. struts2中一个Action处理多个方法
Struts 2 – No result defined for action and result input
更多类似文章 >>
生活服务
热点新闻
分享 收藏 导长图 关注 下载文章
绑定账号成功
后续可登录账号畅享VIP特权!
如果VIP功能使用有故障,
可点击这里联系客服!

联系客服