`

Struts2 参数 对象

 
阅读更多
在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" "http://www.w3.org/TR/html4/loose.dtd">
<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 String getPassword() {
       return password;
    }
    public void setPassword(String password) {
       this.password = password;
    }
    public String getUserName() {
       return userName;
    }

    public void setUserName(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" "http://www.w3.org/TR/html4/loose.dtd">
<html>
    <head>
        <title>Hello</title>
    </head>
    <body>
        <h3><s:property value="msg"/></h3>
    </body>
</html>

新建了一个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 即可: 
        <input type="text" name="user.name"/> 或用标签:<s:textfield name="user.name" label="用户名"/> 
        <input type="text" name="user.pass"/> 或用标签:<s:textfield name="user.pass" label="密 码"/> 
    提交后,Struts 2 即会帮你构造 User 对象(user = new User()),并赋上属性值(user.setName(),user.setPass()),最后 user 对象赋给 Action (xxxAction.setUser(user))。所以要明白有三个必备的东西: 
        1) User 要用一个默认构造方法 2) User 要有对应 name 和 pass 的设置方法 setName() 和 setPass() 3) Action 要有 user 属性的设置方法 setUser(),getUser() 也是要的,至于功用后面能看到。 
其实在 Struts 1 中也有这种用法,不过那是在 BeanUtils 中实现的。

4. 如果 Action 中的属性是 Map<String, User> users; 那么与此对应的表单写法就是:(用标签来写) 
        <s:textfield name="users['one'].name" label="第一个用户名"/> 
        <s:textfield name="users['one'].name" label="第一个密码"/> 
        <s:textfield name="users['two'].name" label="第二个用户名"/> 
        <s:textfield name="users['two'].name" label="第二个密码"/> 
    应该不难想像,这个表单提交后,users 中存储的是什么吧! 
    如果是对于 Action 中的 List 属性,List<User> users; 那么与此对应的表单写法就是: 
        <s:textfield name="users[0].name" label="第一个用户名"/> 
        <s:textfield name="users[0].name" label="第一个密码"/> 
        <s:textfield name="users[1].name" label="第二个用户名"/> 
        <s:textfield name="users[1].name" label="第二个密码"/>

5. 归纳前面3、4、5 几点,Struts2 的 Action 在设置每一个属性时都会 get 一下相应的元素 getUser() 或 getUsers()。 
    对于 3,在设置 user.name 和 user.pass 之前都会 getUser() 来获取 user 属性,如果 user 为 null 就构造 User 对象,然后设置相应的值。假如声明的时候就已构造好 User 对象,如有其他属性如 age=18,并不会被覆盖。 
   对于 4 和 5,也是在设置每一个属性前都会调用 getUsers() 判断声明的 Map 或 List 是否为 null,是则构造对应的 HashMap 或ArrayList() 对象;接着根据 Key 或下标去获取相应位置的元素,如果不存在或为 null 则构造之,然后设置相应属性值。由此可见,若某元素的某个属性未重设值则保留原值,若原来Map或List 已有多个元素,也只会改变到 Key 或索引所对应元素的某个属性。对于 List 有可能出现跳空的情况,如页面只有索引不从 0 开始 
         <s:textfield name="users[1].name" label="第二个用户名"/> 
        <s:textfield name="users[1].name" label="第二个密码"/> 
提交后就会发现,List 属性 users 的第一个元素为 null 了。同时如果尝试一下,你就会发现这里的 List 不能替代为数组 User[] users。 
    这种样法,可在 Struts 1 中实现,但要略施些小节,见我的另一篇日志:提交多行数据到Struts的ActionForm的List属性中 ,行为表现完全一致,只是换到 Struts 2 中一切都不用自己操心。

6. 看第四点,Action 之所以知道该构造什么类型的元素完全是由泛型告诉它的。如果不用泛型(比如用的是 JDK1.4),Action 中仅仅声明的是 Map users; 或 List users; Action 该如何处理呢?它也不知道,只能够帮你构造出无类型的 HashMap 和 ArrayList(),填充不了元素。这就必须在局部类型转换的配置文件中来指定集合元素的类型。例如 Action 为 LoginAction,就要在 LoginAction-conversion.properties 中声明了,格式如下:

    #Element_xxx=复合类型,基中 Element 是固定的,xxx 为属性名 
    #下面表示为 List 属性 users 的元素为 com.unmi.vo.User 类型 
     Element_users=com.unmi.vo.User

    对于 Map,须分别指定 Key 的类型和 Value 的类型 
    #Key_xxx=复合类型,基中 Key 是固定的,xxx 为 map 属性名,下面写成 String 都不行的 
    Key_users=java.lang.String 
    指定 Map 的 Value 的类型与指定 List 元素类型是一样的 
    Element_users=com.unmi.vo.User

难怪 Struts 2 要与 1.5 以上 JDK 使用,泛型比配置来得方便。如果硬要用 1.4 JDK,就只有配置类型了,会多很多 conversion 文件的。在 提交多行数据到Struts的ActionForm的List属性中 中类型的确定由 AutoArrayList() 的构造参数完成。

7. Set 是无序集合,所以无法像 List 那样用数字下标来访问,幸好 Struts 2 可为其指定索引属性。例如,LoginAction 声明为 Set users; (这里好像用泛型只能省得了 Element_users 说明,KeyProperty_users 少不了)。则需在 LoginAction-conversion.properties 中写下: 
    #指定 Set 的元素类型 
    Element_users=com.unmi.vo.User

    #KeyProperty_集合属性名=集合元素的索引属性名,这里为 User 的 name 属性 
    KeyProperty_users=name

此时提交页面这么写,最好提交前能根据输入的用户名自动修动输入框的 name。 
        用户名: <input name="users('scott').name"/> 
        密 码: <input name="users('scott').pass"/> 
显示的时候页面可用标签 
        用户名: <s:property value="users('scott').name"/> 
        密 码: <s:property value="users('scott').pass"/> 
注意前面,访问 Set 元素是用的圆括号,而不同于 Map、List、数组是用中括号。我想一般也犯不着非要用 Set 而不用 List,Struts 2 中用Set 比在 Struts 1 中似乎还麻烦。

8. Struts 2 内建了一批转换器:boolean、char、int、long、float、double 和它们的包装类型;Date,日期格式使用请求所在 Locale的 SHORT 格式;数组,默认元素为字符串,其他类型则要转换每一个元素?(好像是一次性转换完成的);集合,默认元素为字符串XWorkList(String.class, Object[]),其他如 List<Integer> ids,类型为 XWorkList(Integer.class, Object[]),XWorkList 继承自 ArrayList。

9. 类型转换出错由 Struts 来帮你处理,在默认拦截器栈中提供了 conversionError 拦截器,不用你写一点代码逻辑。conversionError 在出错时将错误封装成 fieldError,并放在 ActionContext 中。你所要做的就是遵循它的规则,1) 你的 Action 要继承自ActionSupport,2)在 struts.xml 中声明名为 "input" 的 result,出错时会在 input 逻辑视图显示信息。3)尽量用标签来写输入域(如<s:textfield name="number" label="数量"/>),这样转换出错后,就会像校验失败一样把错误信息显示在每个输入框上面(视模板而定),否则要手工用 <s:fielderror/> 输出在某处。 
默认时输出错误信息为(比如是属性 number,输入的是字符串时):Invalid field value for field "number".你可以改变默认显示,在全局国际化资源文件中加上 xwork.default.invalid.fieldvalue={0}字段类型转换失败!。在某些时候,可能还需要对特定字段指定特别的提示信息, 那么在名为 ActionName.properties 的局部资源文件中加上 invalid.fieldvalue.属性名=提示信息 (如invalid.fieldvalue.number=数量格式错误)

10. 最后是集合属性转换错误时的显示,对于页面中的同名输入框,有多个出错误,如果手工用 <s:fieldError/> 只会显示一条错误,但要是输入页是用标签(如<s:textfield name="number" label="数量"/>),仍会在每一个出错的输入框上都提示。至此类型转换的内容也就完结了。

 

分享到:
评论

相关推荐

    struts2 向结果传参数

    本文将深入探讨如何在Struts2中实现向结果传参数。 首先,理解Struts2的结果类型是关键。Struts2支持多种内置结果类型,如`dispatcher`(默认的,用于转发到JSP)、`stream`(用于处理文件下载)和`redirectAction`...

    struts2参数配置

    ### Struts2参数配置详解 #### 一、概述 在深入了解Struts2框架时,我们不可避免地会接触到各种参数配置。这些配置对于整个框架的运行至关重要。本文将围绕Struts2中的关键配置进行深入探讨,旨在帮助开发者更好地...

    Struts2_入门篇_基本配置_通配符_参数注入_内置对象获取等。。。

    本入门篇主要涵盖了Struts2的基础配置、通配符使用、参数注入以及内置对象的获取,非常适合初学者进行学习。 1. **基础配置**:在Struts2中,基础配置主要通过`struts.xml`文件完成。这个文件定义了Action(动作)...

    struts2 使用action属性接收中文参数(post提交)

    在处理用户请求时,Struts2允许开发者通过Action类来接收和处理参数,包括中文参数。当我们需要通过POST方法提交包含中文字符的数据时,可能会遇到编码问题,因为HTTP请求默认使用的是ASCII编码,而中文字符需要UTF-...

    struts2 接收参数

    7. **Struts2的类型转换**:Struts2提供了内置的类型转换器,可以自动将请求参数转换为Java对象。如果需要自定义转换逻辑,可以实现`Converter`接口。 在`Struts2_0900_ModelDrivenParamInput`这个文件中,可能包含...

    struts2验证框架参数

    在深入探讨Struts2验证框架参数之前,我们首先简要回顾一下Struts2框架本身。Struts2是基于MVC(Model-View-Controller)设计模式的Java Web应用框架,它提供了一种灵活的方式来构建可扩展的企业级Web应用程序。...

    STRUTS2获得作用域、参数响应对象及三种符号说明

    ### STRUTS2获得作用域、参数响应对象及三种符号说明 #### 一、概述 在Struts2框架中,为了更好地管理Web应用程序中的请求、会话和应用范围的数据,Struts2提供了一系列的工具和机制。这包括了对`RequestMap`、`...

    Struts2中Action接收参数的方法

    DomainModel 是 Struts2 中的一种模型对象,可以用来接收参数。具体步骤如下: 1. 定义 Model 类,例如 `User`,并在 Action 中定义该类的对象,例如 `user`。 2. 在 Model 类中,定义属性,例如 `userName`,并...

    Struts2最佳实践之一-在复杂实体对象中,如何将页面参数转换为实体对象

    本篇文章将深入探讨如何在Struts2中实现从复杂实体对象到页面参数的有效转换,以提升开发效率和代码的可维护性。在实际项目开发中,我们经常需要将用户在页面上填写的数据映射到后台的实体对象,Struts2的...

    struts1.x 和 struts2.x向Action里填充jsp参数原理

    本篇文章将深入探讨Struts1.x和Struts2.x在向Action中填充JSP参数的原理。 Struts1.x的工作原理: Struts1的核心是ActionServlet,它是一个实现了Servlet接口的控制器。当用户发起HTTP请求时,请求会被Dispatcher...

    Struts2接收参数

    例如,如果你有一个名为`saveUser`的方法,接收一个`User`对象作为参数,`User`类中有`name`和`email`字段,那么在HTML表单中提交`name`和`email`字段后,Struts2会自动将这些值填充到`User`对象中。 ```java ...

    Struts2中的参数传递

    1. **封装OGNL操作,实现值的传递**:Struts2通过对OGNL表达式的封装,实现从客户端传入的参数到Java对象之间的值传递。这一过程包括但不限于对各种复杂类型的处理,如数组、列表、映射等。 2. **类型转换**:为了...

    struts1和struts2的区别

    此外,Struts2还支持ModelDriven模式,允许使用模型对象来代替Action。 #### 表达式语言 - **Struts1**: 支持JSTL标签库以及EL表达式。但是,相比于Struts2,其功能较为有限。 - **Struts2**: 支持JSTL的同时,...

    Struts2教学视频

    2. 域模型(Domain Model)是Struts2中用于封装业务数据的对象,Action可以直接引用域模型对象,将请求参数绑定到模型中。 以上就是关于Struts2的一些基础知识点,学习Struts2不仅可以帮助理解MVC模式在实际应用中的...

    Struts2视频教程

    ### Struts2核心知识点解析 #### 一、Struts2框架概述 - **定义与特点**:Struts2是一款基于MVC(Model-View-Controller)设计模式的Java Web应用程序框架,它继承了Struts1的优点,同时在设计上更加灵活、易用,...

    马士兵Struts2笔记2013

    在Struts2中,你可以创建领域对象,通过setter和getter方法来接收和设置请求参数,这些对象可以在多个Action之间共享,提高了代码的复用性。 4. **Struts2_2.1.6版本的中文问题** 在某些版本的Struts2中,可能出现...

    Struts2 的接受参数的几种方式

    ### Struts2 接受参数的几种方式 #### 第一种方式:直接在 Action 中设置变量 这种方式是最直接的参数接收方式。当从前端传递参数到后端时,我们需要确保 Action 类中有与这些参数名称相匹配的变量。例如,如果...

    Struts2 Struts2 超好的Struts2 pdf 文档

    6. **值栈(Value Stack)**:值栈是Struts2中的一个核心组件,它存储了请求中的所有对象。ActionContext提供了对值栈的访问,使得视图能够方便地获取和展示数据。 7. **Freemarker和Velocity模板**:Struts2支持...

    struts2参数.txt

    此参数用于确定Struts2框架中对象的类型。它支持`tiger`和`notiger`两种值,具体选择哪种策略取决于应用的需求。 #### 八、`struts.multipart.parser` 指定处理`multipart/form-data`MIME类型的文件上传组件。支持...

    struts2 学习重点笔记

    - **自动填充**:Struts2 自动从 request 中获取数据并填充到 Action 对象中。 - **原理**:通过拦截器实现,拦截器会查找与 Action 类中的 setter 方法相匹配的请求参数,并调用这些方法填充数据。 **3.3 数据传递...

Global site tag (gtag.js) - Google Analytics