Struts2中类型转换配置


类型转换:将jsp页面的请求参数进行类型的转换后再赋值给action的属性

Struts2已经内建了对于String和基本类型的类型转换,比如String<-->int 、String<-->boolean等;

Action属性一定要有getter和setter方法!

Struts2提供了强大的类型转换支持,不仅提供了内置的类型转换器,还可以自定义类型转换器,以满足自定义需求;

Struts2类型转换是通过 params拦截器进行转换;如果转换失败,则 conversionError拦截器拦截该异常,并封装到fieldError中,放入ActionContext中;

Struts2类型转换还支持OGNL表达式,只需要在表单控件的name属性使用ognl表达式即可,比如表单控件的name属性为user.name,则此控件的数据将进入赋值给Action的user属性中的name属性;


一、struts2自带的类型转换

1、普通的string->int类型的转换

参数请求页面:

<%@ taglib prefix="s" uri="/struts-tags" %>
<%--
  Created by IntelliJ IDEA.
  User: yangcs
  Date: 2017/2/6
  Time: 14:59
  To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>类型转换器</title>
</head>
<body>
使用struts2自带的类型转换器对jsp数据类型进行转换(注意使用了OGNL表达式和struts标签)<br>
后面要对这样的带有非String类型的数据输入进行校验操作<br>
具体效果可以看后台<br>
<s:form action="Action008">
    <s:textfield label="姓名" name="name"></s:textfield>
    <s:textfield label="密码" name="password"></s:textfield>
    <s:textfield label="年龄" name="p.age"></s:textfield>
    <s:textfield label="薪水" name="p.salary"></s:textfield>
    <s:submit value="提交"></s:submit>
</s:form>
</body>
</html>

接受参数的action:

package test002;

import Dao.Person;
import com.opensymphony.xwork2.ActionSupport;

/**
 * Created by yangcs on 2017/2/6.
 * 使用struts2自带类型转换器转换类型示例action
 */
public class TypeExchangeAction extends ActionSupport{
    private String name;
    private int password;
    private Person p;

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public int getPassword() {
        return password;
    }

    public void setPassword(int password) {
        this.password = password;
    }

    public Person getP() {
        return p;
    }

    public void setP(Person p) {
        this.p = p;
    }

    public String execute(){
        System.out.println(name);
        System.out.println(password);
        System.out.println(p.getAge());
        System.out.println(p.getSalary());
        return SUCCESS;
    }
}

结果展示页面:

<%@ taglib prefix="s" uri="/struts-tags" %>
<%--
  Created by IntelliJ IDEA.
  User: yangcs
  Date: 2017/2/6
  Time: 14:59
  To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>类型转换器</title>
</head>
<body>
使用struts2自带的类型转换器对jsp数据类型进行转换(注意使用了OGNL表达式和struts标签)<br>
后面要对这样的带有非String类型的数据输入进行校验操作<br>
具体效果可以看后台<br>
<s:form action="Action008">
    <s:textfield label="姓名" name="name"></s:textfield>
    <s:textfield label="密码" name="password"></s:textfield>
    <s:textfield label="年龄" name="p.age"></s:textfield>
    <s:textfield label="薪水" name="p.salary"></s:textfield>
    <s:submit value="提交"></s:submit>
</s:form>
</body>
</html>

2、当输入集合类型的参数时的转换

如果Action的属性为List类型,List<String>lists ,则表单控件的命名方式为 lists[i] ,如 lists[0]表示第1个元素;
如果Action的属性为Map类型,Map<String,Person> maps;则表单控件的命名方式为maps[ ' first ' ].salary ,表示map中key为'first'的value中的salary属性;

参数请求页面:

<%@ taglib prefix="s" uri="/struts-tags" %>
<%--
  Created by IntelliJ IDEA.
  User: yangcs
  Date: 2017/2/6
  Time: 16:28
  To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>类型转换</title>
</head>
<body>
<s:form action="Action009">
    <s:textfield label="姓名" name="lists[0].name"></s:textfield>
    <s:textfield label="密码" name="lists[0].password"></s:textfield>
    <s:textfield label="年龄" name="map['first'].age"></s:textfield>
    <s:textfield label="薪水" name="map['first'].salary"></s:textfield>
    <s:submit value="提交"></s:submit>
</s:form>
</body>
</html>

后台接受参数的action:

package test002;

import Dao.Person;
import Dao.User;
import com.opensymphony.xwork2.ActionSupport;

import java.util.List;
import java.util.Map;

/**
 * Created by yangcs on 2017/2/6.
 * 这个action是使用类型转换成list和map类型的数据的示例
 */
public class TypeExchangeAction02 extends ActionSupport{
    //public List<String> lists;     //这个地方不能定义为private???
    public List<User> lists;     //定义为private还是不行啊!
    private Map<String, Person> map;

    public List<User> getLists() {
        return lists;
    }

    public void setList(List<User> lists) {
        this.lists = lists;
    }

    public Map<String, Person> getMap() {
        return map;
    }

    public void setMap(Map<String, Person> map) {
        this.map = map;
    }

    public String execute() throws Exception{
        System.out.println(lists.get(0).getName());
        System.out.println(lists.get(0).getPassword());
        System.out.println(map.get("first").getAge());
        System.out.println(map.get("first").getSalary());
        return SUCCESS;
    }
}

结果展示页面:

<%@ taglib prefix="s" uri="/struts-tags" %>
<%--
  Created by IntelliJ IDEA.
  User: yangcs
  Date: 2017/2/6
  Time: 16:39
  To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>类型转换结果</title>
</head>
<body>
姓名:<s:property value="lists[0].getName()"></s:property><br>
密码:<s:property value="lists[0].getPassword()"></s:property><br>
年龄:<s:property value="map['first'].getAge()"></s:property><br>
薪水:<s:property value="map['first'].getSalary()"></s:property>
</body>
</html>

二、自定义类型转换器

1.继承DefaultTypeConverter

如果我们自定义一个类型转换器,第一种方法是继承DefaultTypeConverter,并重写 public Object convertValue(ActionContext context,Object value,Class toType);
这个函数的功能是完成双向转换,即从String数组转到Action属性及Action属性转到String;需要注意的是从String数组转到Action属性,而不是String转到Action属性;如果只有一个字符串,则取params[0] 即可;

因此一般此函数的模板代码如下:

public Object convertValue(Map<String, Object> context, Object value,  
            Class toType) {  
        if(toType==String.class){  
            ......  
            return String;  
        }  
        else if(toType==Action属性.class){  
            String params[] = (String[])value;//必须是字符串数组  
            .......  
            return Action属性;  
        }  
        return null;  
    }  

完成自定义类型转换器编写后,如果需要使用此转换器,就需要配置,通常有两种配置方法:

1.局部类型转换文件中配置,仅对特定的Action的特定属性有效,比如在Action1中有aa属性,则仅对Action1的aa属性有效;

2.全局类型转换文件中配置,对某个类型都有效;比如对Person注册了类型转换器,则对任何Person和String的转换都有效;

全局类型转换文件命名为: xwork-conversion.properties,通常放在WEB-INF\classes下;

文件内容如:attributeName=ConvertClass ,比如org.person.Person = org.convert.Converter2
attributeName表示属性名称, convertClass表示转换器的实现类;

局部类型转换文件命名为:ActionName-conversion.properties,放在特定Action的目录下;
文件内容如: typeName=ConvertClass,比如aa=org.convert.Converter1

注意:typeName表示转换类型,convertClass表示转换器的实现类;

代码示例:

Conversion03Action.java

package org.conversion.action;  
  
import org.person.Person;  
  
import com.opensymphony.xwork2.ActionSupport;  
  
public class Conversion03Action extends ActionSupport {  
  
    private Person p ;  
    public String execute()throws Exception{  
        System.out.println(p.getGender());  
        System.out.println(p.getSalary());  
        return SUCCESS;  
    }  
    public Person getP() {  
        return p;  
    }  
    public void setP(Person p) {  
        this.p = p;  
    }  
  
}  

Converter01.java

package org.converter;  
  
import java.util.Map;  
  
import org.person.Person;  
  
import com.opensymphony.xwork2.conversion.impl.DefaultTypeConverter;  
  
public class Converter01 extends DefaultTypeConverter {  
  
    @Override  
    public Object convertValue(Map<String, Object> context, Object value,  
            Class toType) {  
        if(toType==String.class){  
            Person p = (Person)value;  
            return p.getSalary()+","+p.getGender();  
        }  
        else if(toType==Person.class){  
            String params[] = (String[])value;  
            String[]values = params[0].split("\\,");  
            Person p = new Person();  
            p.setGender(values[1]);  
            p.setSalary(Double.parseDouble(values[0]));  
            return p;  
        }  
        return null;  
    }  
  
}  

3.jsp

<%@ page language="java" contentType="text/html; charset=utf-8"  
    pageEncoding="utf-8"%>  
    <%@taglib prefix="s" uri="/struts-tags" %>  
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">  
<html>  
<head>  
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">  
<title>Insert title here</title>  
</head>  
<body>  
<s:fielderror></s:fielderror>  
    <s:form action="conversion03" >  
        <s:textfield label="薪水,性别" name="p"></s:textfield>  
        <s:submit value="提交"></s:submit>  
    </s:form>  
</body>  
</html>  

Conversion03Action-conversion.properties

p=org.convert.Converter01  

2.继承StrutsTypeConverter

StrutsTypeConverter是DefaultTypeConverter的子类,DefaultTypeConverter的类型转换器是在一个函数中进行双向转换,而继承StrutsTypeConverter的类型转换器则是将两个方向分别用两个函数实现:

@Override  
public Object convertFromString(Map context, String[] values, Class toClass) {  
  
}  
  
@Override  
public String convertToString(Map context, Object o) {  
  
}  

将DefaultTypeConverter中的Converter01换成如下代码就可以完成StrutsTypeConverter的类型转换器;

package org.converter;  
  
import java.util.Map;  
  
import org.apache.struts2.util.StrutsTypeConverter;  
import org.person.Person;  
  
public class Converter02 extends StrutsTypeConverter {  
  
    @Override  
    public Object convertFromString(Map context, String[] value, Class toClass) {  
        String params[] = (String[])value;  
        String[]values = params[0].split("\\,");  
        Person p = new Person();  
        p.setGender(values[1]);  
        p.setSalary(Double.parseDouble(values[0]));  
        return p;  
    }  
  
    @Override  
    public String convertToString(Map context, Object o) {  
        Person p = (Person)o;  
        return p.getSalary()+","+p.getGender();  
    }  
}  

xwork-conversion.properties

org.person.Person=org.converter.Converter02  

三、错误处理机制

客户输入错误信息是很正常的事,因此需要对此种行为进行处理,Struts2提供了很好的错误处理机制,是由conversionError拦截器自动完成,我们只需要配置输出什么错误信息即可;

当发生类型转换错误时,conversionError拦截器拦截此错误,并封装成fieldError,将此错误信息放入ActionContext中,并返回input逻辑视图;当然在<action>元素中必须配一个类似于<result name="input">/1.jsp</result>的子元素,以应对类型转换错误;

而为了显示错误信息,则在jsp页面中使用<s:fielderror/>即可显示错误信息;
注意:类型转换的Action在struts.xml中配置所在包需要extends="struts-default",因此在此文件中包含conversionError拦截器;

这时我们需要配置显示的错误信息,错误信息配置方式有两种:

1.配置默认提示信息

在国际化资源文件中配置形如:

xwork.default.invalid.fieldvalue={0},错误;

{0}代表类型转换错误的属性名称;

2.配置Action特定属性错误信息

在Action范围的国际化资源文件中配置形如:

invalid.fieldvalue.attributeName= 内容

attributeName是Action中的属性名称;

我们在上面的程序中添加类型转换错误的消息:

在Conversion04Action_zh_CN.properties中添加:

<span style="font-family:'Microsoft YaHei';">invalid.fieldvalue.p=person类型转换错误;</span> 

意思是对p属性配置了特定的错误提示信息,当p属性类型转换错误后就会显示此信息;

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 159,015评论 4 362
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 67,262评论 1 292
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 108,727评论 0 243
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 43,986评论 0 205
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 52,363评论 3 287
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,610评论 1 219
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 31,871评论 2 312
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,582评论 0 198
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,297评论 1 242
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,551评论 2 246
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 32,053评论 1 260
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,385评论 2 253
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 33,035评论 3 236
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,079评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,841评论 0 195
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 35,648评论 2 274
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,550评论 2 270

推荐阅读更多精彩内容

  • Spring Cloud为开发人员提供了快速构建分布式系统中一些常见模式的工具(例如配置管理,服务发现,断路器,智...
    卡卡罗2017阅读 134,100评论 18 139
  • action中如何接受页面传过来的参数 第一种情况:(同名参数) 例如:通过页面要把id=1 name=tom a...
    清枫_小天阅读 2,860评论 1 22
  • 标签 如果要配置的标签,那么必须要先配置标签,代表的包的概念。 包含的属性 name包的名称,要求是唯一的,管理a...
    偷偷得路过阅读 1,171评论 0 0
  • 概述 什么是Struts2的框架Struts2是Struts1的下一代产品,是在 struts1和WebWork的...
    inke阅读 2,182评论 0 50
  • 哈哈哈!大笑三声!姐终于变成一个标准的人了!最近三天也坚持锻炼,每天发一次跑步机数据太烦人了,就攒一起发一下。 ...
    花落月阅读 266评论 0 1