3. 类型转换初体验 !--圣思园Struts 2.2笔记

1,每一次struts2请求都会生成一个action对象。

Struts2 的类型转换,对于 8 个原生数据类型以及 Date,String 等常见类型,
Struts2 可以使用内建的类型转换器实现自动的转换;但对于自定义的对象类型来说,
就需要我们自己指定类型转换的方式了。

类型转换范例:

页面提交请求:
    <form action="userAction.action">
    <!-- 以;分割 -->
        USER:<input id="user" name="user" /><BR/>
        <input type="submit" value="submit"/>
    </form>
struts2过滤器根据userAction.action请求找到struts.xml配置文件中相应的配置:
            <action name="userAction" class="discovery.struts2.login.UserAction">
                <result name="success">/webs2/userInfo.jsp</result>
            </action>
根据配置创建discovery.struts2.login.UserAction的实例,
注:
对于自定义的类型转换器来说需要提供 3 个信息:Action 的名字、
Action 中待转换的属性名以及该属性对应的类型转换器。其中
Action 的名字是通过属性文件名来获得的、 Action 中待转换的属性
名是通过属性文件中的 key 来获得的,该属性对应的类型转换器是
通过该 key 所对应的 value 来获得的。

若在相同包下面找到配置文件UserAction-conversion.properties
并且配置文件中定义了类型转换参数
# UserAction中需要类型转换的属性=类型转换器
# 说明需要对UserAction的user属性使用该类型转换器进行转换
user=discovery.struts2.coverter.UserCoverter
则先生成discovery.struts2.coverter.UserCoverter的对象,调用方法:
public Object convertValue(Map context, Object value, Class toType);
package discovery.struts2.coverter;

import java.util.Map;
import java.util.StringTokenizer;

import ognl.DefaultTypeConverter;
import discovery.struts2.login.bean.User;

/**
 * 类型转换器
 */

public class UserCoverter extends DefaultTypeConverter {
    /**
     * 类型转换:
     * 将页面字符串转换为后台对象
     * 将后台对象转换为页面字符串
     */

    @Override
    public Object convertValue(Map context, Object value, Class toType) {
        if(User.class == toType){
            System.out.println("将页面字符串转换为后台对象");
            String[] str = (String[])value;
            String firstValue = str[0];
            StringTokenizer st = new StringTokenizer(firstValue, ";");
            String username = st.nextToken();
            String password = st.nextToken();
            User user = new User();
            user.setPassword(password);
            user.setUsername(username);
            return user;
        }else if(String.class == toType){
            System.out.println("将后台对象转换为页面字符串");
            User user = (User)value;
           
            String username = user.getUsername();
            String password = user.getPassword();
           
            String userInfo = "username: " + username + ", password: " + password;
           
            return userInfo;
        }
        return null;
    }
}
返回user对象会被通过调用UserAction对象的setUser()方法设置到UserAction对象中。
设置完成之后调用UserAction对象的public String execute() throws Exception方法返回结果。
package discovery.struts2.login;
import com.opensymphony.xwork2.ActionSupport;
import discovery.struts2.login.bean.User;
public class UserAction extends ActionSupport {
    private User user;
    public User getUser() {
        return user;
    }
    public void setUser(User user) {
        this.user = user;
    }
    
    @Override
    public String execute() throws Exception {
        System.out.println(user.getUsername());
        System.out.println(user.getPassword());
        return SUCCESS;
    }
}
将返回的结果与struts.xml配置文件的相关配置(result)相匹配:
<result name="success">/webs2/userInfo.jsp</result>
请求转发到userInfo.jsp页面。
<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
//引入struts2 标签库
<%@ taglib prefix="s" uri="/struts-tags" %>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
  <head>
    <title>userInfo!</title>
  </head>  
  <body>
    //使用标签获取user数据时,将调用discovery.struts2.coverter.UserCoverter类型转换器将user信息转换为页面显示的数据;
          USER:<s:property value="user"/>
  </body>
</html>


可以使用 Struts2 框架自带的类型转换器 StrutsTypeConverter 简化类 型 转 换 代 码 的 编 写 ,
 StrutsTypeConverter 继 承 于DefaultTypeConverter 父 类 , 并 且 提 供 了 两 个 抽 象 方 法 :
convertFromString 与 convertToString,
分别表示从页面的字符串转换为后台对象以及从后台对象转换为页面的字符串,
我们只需实现这两个抽象方法即可实现类型转换。
public abstract class StrutsTypeConverter
extends com.opensymphony.xwork2.conversion.impl.DefaultTypeConverter

Base class for type converters used in Struts. This class provides two abstract methods that are used to convert both to and from strings -- the critical functionality that is core to Struts's type coversion system.

Type converters do not have to use this class. It is merely a helper base class, although it is recommended that you use this class as it provides the common type conversion contract required for all web-based type conversion.

There's a hook (fall back method) called performFallbackConversion of which could be used to perform some fallback conversion if convertValue method of this failed. By default it just ask its super class (Ognl's DefaultTypeConverter) to do the conversion.

To allow the framework to recognize that a conversion error has occurred, throw an XWorkException or preferable a TypeConversionException. 

package discovery.struts2.coverter;

import java.util.Map;
import java.util.StringTokenizer;

import org.apache.struts2.util.StrutsTypeConverter;

import discovery.struts2.login.bean.User;

public class UserStruts2Coverter extends StrutsTypeConverter {

    @Override
    public Object convertFromString(Map context, String[] values, Class toClass) {
        System.out.println("convertFromString将页面字符串转换为后台对象");
        String firstValue = values[0];
        StringTokenizer st = new StringTokenizer(firstValue, ";");
        String username = st.nextToken();
        String password = st.nextToken();
        User user = new User();
        user.setPassword(password);
        user.setUsername(username);
        return user;
    }

    @Override
    public String convertToString(Map context, Object o) {
        System.out.println("convertToString将后台对象转换为页面字符串");
        User user = (User)o;
       
        String username = user.getUsername();
        String password = user.getPassword();
       
        String userInfo = "username: " + username + ", password: " + password;
       
        return userInfo;
    }

}

修改配置文件UserAction-conversion.properties:
# UserAction中需要类型转换的属性=类型转换器
# user=discovery.struts2.coverter.UserCoverter
user=discovery.struts2.coverter.UserStruts2Coverter

StrutsTypeConverter源代码:
package org.apache.struts2.util;

import java.util.Map;

import com.opensymphony.xwork2.conversion.impl.DefaultTypeConverter;

public abstract class StrutsTypeConverter extends DefaultTypeConverter {

    public Object convertValue(Map context, Object o, Class toClass) {
        if (toClass.equals(String.class)) {
            return convertToString(context, o);
        } else if (o instanceof String[]) {
            return convertFromString(context, (String[]) o, toClass);
        } else if (o instanceof String) {
            return convertFromString(context, new String[]{(String) o}, toClass);
        } else {
            return performFallbackConversion(context, o, toClass);
        }
    }

    /**
     * Hook to perform a fallback conversion if every default options failed. By default
     * this will ask Ognl's DefaultTypeConverter (of which this class extends) to
     * perform the conversion.
     */

    protected Object performFallbackConversion(Map context, Object o, Class toClass) {
        return super.convertValue(context, o, toClass);
    }


    /**
     * Converts one or more String values to the specified class.
     */

    public abstract Object convertFromString(Map context, String[] values, Class toClass);

    /**
     * Converts the specified object to a String.
     */

    public abstract String convertToString(Map context, Object o);
}


批量类型转换:

提交请求页面:/reborn/rebornWeb/webs2/userList.jsp
    <form action="userListAction.action">
    <!-- 以;分割 -->
        USER1:<input name="user" /><BR/>
        USER2:<input name="user" /><BR/>
        USER3:<input name="user" /><BR/>
        USER4:<input name="user" /><BR/>
        <input type="submit" value="submit"/>
    </form>
                            

Action:
package discovery.struts2.login;

import java.util.List;

import com.opensymphony.xwork2.ActionSupport;

import discovery.struts2.login.bean.User;

public class UserListAction extends ActionSupport {
    private List<User> user;
   
    public List<User> getUser() {
        return user;
    }

    public void setUser(List<User> user) {
        this.user = user;
    }

    @Override
    public String execute() throws Exception {
        for(User u:user){
            System.out.println(u.getUsername());
        }
        return SUCCESS;
    }
}

struts.xml
            <action name="userListAction" class="discovery.struts2.login.UserListAction">
                <result name="success">/webs2/userListInfo.jsp</result>
            </action>

转换器配置:/reborn/src/discovery/struts2/login/UserListAction-conversion.properties
# UserListAction中需要类型转换的属性=类型转换器
user=discovery.struts2.coverter.UserListStruts2Coverter

转换器:
package discovery.struts2.coverter;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.StringTokenizer;
import org.apache.struts2.util.StrutsTypeConverter;
import discovery.struts2.login.bean.User;
public class UserListStruts2Coverter extends StrutsTypeConverter {
    @Override
    public Object convertFromString(Map context, String[] values, Class toClass) {
        List<User> list = new ArrayList<User>();
        for (String value : values)
        {
            StringTokenizer st = new StringTokenizer(value, ";");
            User user = new User();
            user.setUsername(st.nextToken());
            user.setPassword(st.nextToken());
            list.add(user);
        }
        return list;
    }
    @Override
    public String convertToString(Map context, Object o) {
        List<User> list = (List<User>) o;
        StringBuffer buffer = new StringBuffer();
        for (User user : list)
        {
            String username = user.getUsername();
            String password = user.getPassword();
            buffer.append("username: ").append(username).append(" ,password: ")
                    .append(password).append(" ");
        }
        return buffer.toString();
    }
}
显示页面:/reborn/rebornWeb/webs2/userListInfo.jsp
<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
<%@ taglib prefix="s" uri="/struts-tags" %>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
  <head>
    <title>userInfo!</title>
  </head>
  
  <body>
          USER:<s:property value="user"/>
  </body>
</html>
 

全局转换器:

不管是哪个Action ,只要使用到了某个属性,就使用特定的转换器。
上面所述转换器为局部转换器,对某个Action某个属性使用哪个转换器。

src下新建xwork-conversion.properties

#要转换的类 =类型转换器:只要Action中包含了该类类型的属性,便使用该转换器转换。
discovery.struts2.login.bean.User=discovery.struts2.coverter.UserStruts2Coverter












posted @ 2014-02-16 22:59  龍變  阅读(220)  评论(0编辑  收藏  举报