struts2(五)类型转换

Web应用程序的交互都是建立在HTTP之上的,Http请求参数都是字符串类型,服务器接收到的来自用户的数据只能是字符串或者是字符数组,而Java是强类型的语言,Web应用的对象可能使用如整数(int)、浮点数(float)、日期(Date)或者自定义数据类型等,为此要求在服务端把字符串参数转换为相应的数据类型。

从一个 HTML 表单到一个 Action 对象, 类型转换是从字符串到相应类型,表现层数据的流向和所需的类型转换如下图,

在 struts2 中, 把请求参数映射到 action 属性的工作由 Parameters 拦截器负责, 它是默认的 defaultStack 拦截器中的一员. Parameters 拦截器可以自动完成字符串和基本数据类型之间转换,比如转换为int、float等简单数据类型是不需要我们自己定义转换器去转换的,struts2内部本身就为我们提供了转换的方法,但像一些复杂的类型和我们自定义的数据类型还是需要我们自己去写转换器去转换的。struts2提供了很好的扩展性,开发者可以方便地开发自定义类型转换器,完成字符串和自定义复合类型之间的转换(例如,完成字符串到Person实例的转换)。

如果类型转换过程中发生未知异常类型转换器开发者不用关心异常处理逻辑,struts2的conversionError会自动处理该异常,并且在页面上生成提示信息。

大部分常用类型不需要开发者理会,它们通过struts2内建的类型转换器完成,struts内建类型转换器已经能够完成字符串类型与这些类型之间相互的类型转换:boolean和Boolean,char和Character,int和Integer,long和Long,float和Float,double和Double,Date,数组,集合等。

开发者要关注的是将字符串转换成复合类型,可以通过实现OGNL提供的TypeConvert接口,或者实现TypeConvert接口的DefaultTypeConvert类来,或者借助OGNL表达式的支持(以简单方式),实现自定义的类型转换器。先来看一个Action类的代码。

public class User{
    private String name;
    private String pass;

    // name的setter和getter方法
    public void setName(String name){
        this.name = name;
    }
    public String getName(){
        return this.name;
    }

    // pass的setter和getter方法
    public void setPass(String pass){
        this.pass = pass;
    }
    public String getPass(){
        return this.pass;
    }
}

Action里包含了一个User类型的属性,这个属性需要进行类型转换,struts2框架接受到HTTP请求参数后,要将这些请求参数封装成User对象。

struts2提供的OGNL表达式允许开发者无须任何特殊处理,只需要在定义表单域时使用OGNL表达式来定义表单域的name属性,jsp页面代码如下。

<s:form action="login">
    <!-- 该表单域封装的请求参数名为user.name -->
    <s:textfield name="user.name" label="用户名"/>
    <!-- 该表单域封装的请求参数名为user.pass -->
    <s:textfield name="user.pass" label="密码"/>
    <tr>
        <td colspan="2"><s:submit value="转换" theme="simple"/>
        <s:reset value="重填" theme="simple"/></td>
    </tr>
</s:form>

上面代码定义了两行单行文本框,对应两个请求参数,表单请求参数名并不是普通参数,而是user.name,user.pass的形式,这就是OGNL表达式的形式,struts2会把user.name参数的值复制给Action实例的user属性的name属性,并将user.pass参数的值赋值给Action实例的user属性的pass属性。

struts2通过这种方式可以将普通请求参数转换成复合类型对象,但在使用时有几点需要注意。

1. 由于struts2将通过反射来创建一个复合类(User类)的实例,因此系统必须为该复合类提供无参构造器。

2. 如果希望使用user.name请求参数的形式为Action实例的user属性的name属性赋值,则必须为user属性对应的复合类(User类)提供setName()方法,因为struts2是通过调用该方法来为该属性赋值的。Action类中还应该包含getUser()方法。

极端情况下,可以直接产生Collection,或者Map实例。看如下的Action类片段。

public class LoginAction extends ActionSupport
{
    // Action类里包含一个Map类型的成员变量
    // Map的value类型为User类型
    private Map<String , User> users;

    // users的setter和getter方法
    public void setUsers(Map<String , User> users)
    {
        this.users = users;
    }
    public Map<String , User> getUsers()
    {
        return this.users;
    }

    public String execute() throws Exception
    {
        // 在控制台输出Struts 2封装产生的Map对象
        System.out.println(getUsers());
        // 根据Map集合中key为one的User实例来决定控制逻辑
        if (getUsers().get("one").getName().equals("crazyit.org")
            && getUsers().get("one").getPass().equals("leegang") )
        {
            addActionMessage("登录成功!");
            return SUCCESS;
        }
        addActionMessage("登录失败!!");
        return ERROR;
    }
}

这里Action类定义了一个users属性,该属性的类型是Map

<s:form action="login">
    <s:textfield name="users[‘one‘].name" label="第one个用户名"/>
    <s:textfield name="users[‘one‘].pass" label="第one个密码"/>
    <s:textfield name="users[‘two‘].name" label="第two个用户名"/>
    <s:textfield name="users[‘two‘].pass" label="第two个密码"/>
    <tr>
        <td colspan="2"><s:submit value="转换" theme="simple"/>
        <s:reset value="重填" theme="simple"/></td>
    </tr>
</s:form>

将表单域的name属性设置为“Action属性名[‘key值’].属性名”的形式,其中“Action属性名”是Action类里包含的Map类型属性,后一个属性名则是Map对象里复合类型对象的属性名。通过这种方式,struts2可以将HTTP请求参数转换成Map属性。

如果要访问Action的Map类型,也可以用OGNL表达式,代码如下。

key为one的用户名为:<s:property value="users[‘one‘].name"/><br/>
key为one的密码为:<s:property value="users[‘one‘].pass"/><br/>
key为two的用户名为:<s:property value="users[‘two‘].name"/><br/>
key为two的密码为:<s:property value="users[‘two‘].name"/><br/>

如果把LoginAction中的users属性改为List,即如果需要struts2将用户请求参数封装为List类型属性,一样可以利用OGNL表达式做到,只要通过索引来指定要将请求参数转换成List的哪个元素,下面JSP页面里的表单元素的name属性可实现将HTTP请求参数转换成List类型。

<s:form action="login">
    <s:textfield name="users[0].name" label="第一个用户名"/>
    <s:textfield name="users[0].pass" label="第一个密码"/>
    <s:textfield name="users[1].name" label="第二个用户名"/>
    <s:textfield name="users[1].pass" label="第二个密码"/>
    <tr>
        <td colspan="2"><s:submit value="转换" theme="simple"/>
        <s:reset value="重填" theme="simple"/></td>
    </tr>
</s:form>

上面代码中定义表单域时指定第一个文本域的name为users[0].name,struts2将会把该文本域所代表的请求参数转换成users集合第一个元素的name属性。

如果想输出Action中List属性里各集合元素的属性值,则可通过在集合属性后增加索引来访问,代码如下。

第一个User实例的用户名为:<s:property value="users[0].name"/><br/>
第一个User实例的密码为:<s:property value="users[0].pass"/><br/>
第二个User实例的用户名为:<s:property value="users[1].name"/><br/>
第二个User实例的密码为:<s:property value="users[1].name"/><br/>
时间: 2024-11-08 22:20:12

struts2(五)类型转换的相关文章

struts2的类型转换

1.struts2可以自动转换8大基本数据类型和String以及Date类型 login.jsp: login.jsp <%@ page language="java" import="java.util.*" pageEncoding="utf-8"%> <% String path = request.getContextPath(); String basePath = request.getScheme()+"

Struts2自定义类型转换,和处理类型转换错误

Struts2自定义类型转换: 从前台接受到的类型全部是字符串,Struts2自带的一些基本类型转换有时不能满足我们的特别需要,如:日期字符串输入格式,还有一些自定义的类,直接传到后台,我们需要一些自己的转换器: 例: 我有一个Point类型: package cn.jnit.bean; public class Point { private Integer x; private Integer y; public Point() { } public Point(Integer x, Int

java之struts2之类型转换

在使用servlet开发中,表单中提交的数据到servlet后都是字符串类型,需要程序员手动进行类型转换. 但是到struts2后,基本数据类型struts2都可以转换.但是如果是自定义类型,struts2也不能自动转换. 这个时候需要程序员进行手动转换或者使用struts2提供的类型转换机制来实现. 案例:假如在页面上提交一个坐标点,如何在处理类中获取的也是坐标对象信息. 使用struts2的类型转换机制步骤: 1.编写类型转换器,该类型转换器继承StrutsTypeConverter ,由o

Struts2的类型转换(下)

Struts2提供的类型转换: Struts2提供的是一个名叫StrutsTypeConverter的抽象类,这个类实际上是DefaultTypeConverter的子类.当我们继承自该抽象类 时,要求我们实现下面的两个方法: @Override public Object convertFromString(Map arg0, String[] arg1, Class arg2) { // TODO Auto-generated method stub return null; } @Over

Struts2的类型转换(上)

传统的类型转换.(略) Struts2中提供了内置的基本的类型转换器,可以实现基本类型的自动转换,包括: Integer, Float, Double, Decimal Date and Datetime Arrays and Collections Enumerations Boolean BigDecimal 基于OGNL(对OGNL暂时不熟悉)的类型转换: 以一个User类为例: public class User { private String name; private String

Struts2日期类型转换

针对日期类java.util.Date进行类型转换,要求客户端使用“yyyy-MM-dd”,“yyyy/MM/dd”中的任意一种输入,并以“yyyy-MM-dd”的格式输出,该类型转换应用于全局范围 public class User { private String username;//名字 private Integer age;//年龄 private Date birthday;//生日 public String getUsername() { return username; }

struts2自定义类型转换

struts2 类型转换很智能,他会帮我们自动转换类型,struts会自动转换4类8种原生数据类型和String ,Date,当我们自己定义的类型就不会转换了,需要我们自己去编写类型转换器. 原理:类型转换有两个类,DefaultTypeConverter和Struts2TypeConverter,Struts2TypeConverter继承DefaultTypeConveter,DefaultTypeConverter里面就一个方法convertValue. package com.sheng

Struts2 日期类型转换

针对日期类java.util.Date进行类型转换,要求客户端使用“yyyy-MM-dd”,“yyyy/MM/dd”中的任意一种输入,并以“yyyy-MM-dd”的格式输出,该类型转换应用于全局范围 先定义一个实体类 package cn.entity; import java.util.Date; public class User { private String username;//名字 private Integer age;//年龄 private Date birthday;//生

Struts2数据类型转换之自定义数据类型转换(二)

对于自定义的类型转换器来说,需要提供三个信息: Action的名字.Action中带转换的属性名.该属性对应的转换器类 其中,action的名字是通过属性文件名来获取的,action中待转换的属性名是通过文件中的key获得的,该属性对应的转换器类是通过该key对应的value获取的. 例如上节中的UserAction-converter.properties,其文件内容为: user=com.test.converter.UserConverter 这就告诉我们,对于UserAction这个ac

Struts2(五):ActionSupport

我们在上一章节中的一个列子中使用到了一个标识跳转到登录页面的例子: 示例是这样写的: index.jsp: <br/> <a href="gotoLoginPage">login page</a> 这里表示要调转到登录login.jsp页面,不过这个跳转是一个action. 在struts.xml中对应注册: 1 <!-- default class="com.opensymphony.xwork2.ActionSupport&quo