一、Struts2 类型转换介绍
类型转换:解析HTTP请求参数,将Http请求参数赋值给Action的属性;比如:
<s:form action="valid" >
<s:textfield label="用户名" name="name"></s:textfield>
<s:password label="密码" name="password"></s:password>
<s:textfield label="年龄" name="age"></s:textfield>
<s:submit value="提交"></s:submit>
</s:form>
此处将名为name、password、age的值赋值给Action的属性,类型转换是指这个赋值过程中可能出现的类型不一致问题而做出的转换,因为HTTP参数都是字符串类型的;因此从String类型的age参数传给int类型的age属性时,就需要类型转换,当然这些struts2框架已经做完了,开发人员不需要自行处理;
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类型转换
package org.conversion.action;
import org.person.Person;
import com.opensymphony.xwork2.ActionSupport;
public class Conversion01Action extends ActionSupport {
private String name;
private int age;
private Person p ;
public String execute()throws Exception{
System.out.println(name);
System.out.println(age);
System.out.println(p.getGender());
System.out.println(p.getSalary());
return SUCCESS;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public Person getP() {
return p;
}
public void setP(Person p) {
this.p = p;
}
}
<%@ 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="conversion01" >
<s:textfield label="姓名" name="name"></s:textfield>
<s:textfield label="年龄" name="age"></s:textfield>
<s:textfield label="性别" name="p.gender"></s:textfield>
<s:textfield label="薪水" name="p.salary"></s:textfield>
<s:submit value="提交"></s:submit>
</s:form>
</body>
</html>
补充:List 和 Map 的Action属性的类型转换问题
前面我们将的都是基本 类型和自定义类型,因此这里我们将讲述集合类型的类型转换问题;
对于List元素来说,内容如 : Element_attributeName=typeName;
比如,此处没有使用泛型,而是使用了局部类型转换文件:
Conversion02Action.java
package org.conversion.action;
import java.util.List;
import java.util.Map;
import org.person.Person;
import com.opensymphony.xwork2.ActionSupport;
public class Conversion02Action extends ActionSupport {
private List lists;
private Map maps;
public String execute()throws Exception{
System.out.println(((Person)lists.get(0)).getGender());
System.out.println(((Person)lists.get(0)).getSalary());
System.out.println(((Person)maps.get("one")).getGender());
System.out.println(((Person)maps.get("one")).getSalary());
return SUCCESS;
}
public List getLists() {
return lists;
}
public void setLists(List lists) {
this.lists = lists;
}
public Map getMaps() {
return maps;
}
public void setMaps(Map maps) {
this.maps = maps;
}
}
Conversion02Action-conversion.properties
Element_lists=org.person.Person
Key_maps=java.lang.String
Element_maps=org.person.Person
2.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="conversion02" >
<s:textfield label="list1.salary" name="lists[0].salary"></s:textfield>
<s:textfield label="list1.gender" name="lists[0].gender"></s:textfield>
<s:textfield label="map1.gender" name="maps['one'].gender"></s:textfield>
<s:textfield label="map1.salary" name="maps['one'].salary"></s:textfield>
<s:submit value="提交"></s:submit>
</s:form>
</body>
</html>
Element_lists=org.person.Person
Key_maps=java.lang.String
Element_maps=org.person.Person
三、自定义类型转换器
1.继承DefaultTypeConverter
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;
}
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;
}
}
<%@ 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
@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
四、错误处理机制
在国际化资源文件中配置形如:
invalid.fieldvalue.p=person类型转换错误;
意思是对p属性配置了特定的错误提示信息,当p属性类型转换错误后就会显示此信息;