- 浏览: 375245 次
- 性别:
- 来自: 大连
文章分类
最新评论
-
Kitty19872010:
在书《Principles of Concurrent and ...
Java中的volatile关键字 -
奇林醉:
受用了!
JAVA Clone机制 -
guji528:
对result type做了详细描述,好。
struts2 strus.xml中result类型及含义 -
water84222:
dc444 写道为了回帖还做了个测验,真麻烦。
楼主对vol ...
Java中的volatile关键字 -
dc444:
为了回帖还做了个测验,真麻烦。
楼主对volatile是有一 ...
Java中的volatile关键字
为什么会有类型转换?
HTTP协议中传递的任何内容都是String类型的,所以一旦我们在服务器上需要一个非String类型的对象,例如:int或者Date,那么我们就需要在收到 HTTP请求的数据的时候,首先将String类型的数据变换为我们需要的对应类型的数据,之后再使用。这个过程就是类型转换
类型转换在Struts2中是透明的,即Struts2内置了类型转换机制。
转换原理:
以一个例子来说明如何使用Struts2内置的类型转换功能。加入我们希望用户在画面上输入一个字符形式的坐标点,例如(33,2)而我们希望在程序中得到一个Point(33, 2)的类型与之对应。
要想达到上面的功能我们需要一个名字位:ActionName-conversion.properties的文件,在文件中定义Action中的属性和画面字段之间的转换关系。例如:
point = com.jpleasure.convertor.PointConverter
也就是说画面一个叫做point的项目(input类型,name为point)提交到服务器上之后,在向Action中的point属性赋值之前需要使用 PointConverter将字符串转换为Point类,在Action中的point属性向画面显示的时候需要使用PointConverter将 Point类转换为字符串类型。
其中PointConverter需要实现ognl.TypeConverter接口。TypeConverter有两个接口,一个负责将字符串转变为对象类型,另一个负责将对象类型转换为字符串类型,分别对应着内容的提交和显示。
有些时候我们希望所有的Point类在默认的情况下使用PointConverter来转换,这时候我们需要定义全局的Converter类。这可以在xwork-conversion.properties文件中定义,例如:
com.jpleasure.Point = com.jpleasure.convertor.PointConverter
在Struts2中提供了一个TypeConverter接口的默认实现:
org.apache.struts2.action.util.StrutsTypeConverter
这个类有两个默认的抽象转换方法和performFallbackConversion,performFallbackConversion方法负责处理类型转换出错的处理。
在自定义TypeConverter的时候,可以实现TypeConverter接口,之后编写TypeConverter的转换方法,也可以从 StrutsTypeConverter继承而来,StrutsTypeConverter本身实现了TypeConverter接口,并且实现了基本的转换方法。
内建的转换:
Struts2内建了对以下类型的转换的支持:
String
boolean / Boolean
char / Character
int / Integer, float / Float, long / Long, double / Double
dates - 使用HTTP 请求对应地域(Locale)的SHORT形式转换字符串和日期类型。
arrays -每一个字符串内容可以被转换为不同的对象
collections - 转换为Collection类型,默认为ArrayList类型,其中包含String类型。
对于Array类型和Collection类型,需要对其中的每一个元素进行单独的转换。
自定义TypeConverter:
使用如下的代码自定义需要的TypeConverter
public class MyConverter extends StrutsTypeConverter {
public Object convertFromString(Map context, String[] values, Class toClass) {
.....
}
public String convertToString(Map context, Object o) {
.....
}
}
为了让Struts2框架发现类型转换的错误,需要在出错的情况下在上述的两个方法中抛出XWorkException或者TypeConversionException。
我们使用一个例子来展现如何实现TypeConvertor类型:
// Point 类
package com.jpleasure.conversion;
/**
* Created by IntelliJ IDEA.
* User: ma.zhao@dl.cn
* Date: 2007/09/04
* Time: 12:33:43
* To change this template use File | Settings | File Templates.
*/
public class Point {
private int x;
private int y;
public Point() {
}
public Point(int x, int y) {
this.x = x;
this.y = y;
}
public int getX() {
return x;
}
public void setX(int x) {
this.x = x;
}
public int getY() {
return y;
}
public void setY(int y) {
this.y = y;
}
public String toString() {
StringBuffer sb = new StringBuffer("Point(");
sb.append(x).append(", ").append(y).append(")");
return sb.toString();
}
}
// PointConvertor 类
package com.jpleasure.conversion;
import org.apache.struts2.util.StrutsTypeConverter;
import java.util.Map;
/**
* Created by IntelliJ IDEA.
* User: ma.zhao@dl.cn
* Date: 2007/09/04
* Time: 12:34:18
* To change this template use File | Settings | File Templates.
*/
public class PointConvertor extends StrutsTypeConverter {
// 从字符串转换为对象的方法。
public Object convertFromString(Map map, String[] strings, Class aClass) {
if (strings.length > 0) {
String pointStr = strings[0];
String[] pointStrArray = pointStr.split(",");
if (pointStrArray.length == 2) {
Point p = new Point();
p.setX(Integer.parseInt(pointStrArray[0]));
p.setY(Integer.parseInt(pointStrArray[1]));
return p;
} else {
return null;
}
} else {
return null;
}
}
// 从对象转换为字符串的方法。
public String convertToString(Map map, Object o) {
if (o instanceof Point) {
return o.toString();
} else {
return "";
}
}
}
// 测试用PointAction类
package com.jpleasure.action;
import com.jpleasure.conversion.Point;
import com.opensymphony.xwork2.ActionSupport;
/**
* Created by IntelliJ IDEA.
* User: ma.zhao@dl.cn
* Date: 2007/09/04
* Time: 12:45:11
* To change this template use File | Settings | File Templates.
*/
public class PointAction extends ActionSupport {
private Point point;
public Point getPoint() {
return point;
}
public void setPoint(Point point) {
this.point = point;
}
public String execute() {
return SUCCESS;
}
}
// JSP文件
<%--
Created by IntelliJ IDEA.
User: ma.zhao@dl.cn
Date: 2007/09/04
Time: 12:47:40
To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%@ taglib prefix="s" uri="/struts-tags" %>
<html>
<head><title>Point Page</title></head>
<body>
<s:form action="point" namespace="/point" method="post">
<s:textfield name="point"/>
<s:property value="point"/>
<s:submit/>
</s:form>
</body>
</html>
// PointAction配置文件类。
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE struts PUBLIC
"-//Apache Software Foundation//DTD Struts Configuration 2.0//EN"
"http://struts.apache.org/dtds/struts-2.0.dtd">
<struts>
<package name="point" namespace="/point" extends="struts-default">
<action name="point" class="com.jpleasure.action.PointAction">
<result>/point/Point.jsp</result>
<!-- 定义input的result是为了处理转换出错的情况,在输入格式不正确的情况下转移到这个画面 -->
<result name="input">/point/Point.jsp</result>
</action>
<!-- Add actions here -->
</package>
</struts>
复杂的类型转换:
(1)处理Null值
有些时候我们会被NullPointerException搞的焦头烂额,为什么系统不能为我们定义了但是没有初始化的对象建立一个空的Object的引用呢?Struts2有这个功能,但是在默认情况下Struts2关闭了这个功能,要想开启这个功能,需要在ParameterInterceptor开始处理参数之前在ValueStack中将一个值开启,这个值是:InstantiatingNullHandler.CREATE_NULL_OBJECTS。
在Java代码中InstantiatingNullHandler.CREATE_NULL_OBJECTS的值是:xwork.NullHandler.createNullObjects
创建空值对象的规则为:
* 如果属性声明为Collection或List, 将返回一个ArrayList并赋值给空引用.
* 如果属性声明为Map, 将返回一个HashMap并赋值给空引用.
* 如果空值属性是一个带有无参构造函数的简单Bean, 将使用ObjectFactory.buildBean(java.lang.Class, java.util.Map)方法创建一个实例.
(2)Collection和Map
简单List转换
//JSP代码
<%--
Created by IntelliJ IDEA.
User: mazhao
Date: 2007/09/04
Time: 12:47:40
To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%@ taglib prefix="s" uri="/struts-tags" %>
<html>
<head><title>Point Page</title></head>
<body>
<s:form action="point" namespace="/point" method="post">
<s:textfield label="Point" name="point"/>
<s:textfield label="References" name="references"/>
<s:textfield label="References" name="references"/>
<s:textfield label="References" name="references"/>
<s:textfield label="References" name="references"/>
<s:textfield label="References" name="references"/>
<s:property value="point"/>
<s:submit/>
</s:form>
</body>
</html>
//Action代码
package com.jpleasure.action;
import com.jpleasure.conversion.Point;
import com.opensymphony.xwork2.ActionSupport;
import java.util.List;
/**
* Created by IntelliJ IDEA.
* User: ma.zhao@dl.cn
* Date: 2007/09/04
* Time: 12:45:11
* To change this template use File | Settings | File Templates.
*/
public class PointAction extends ActionSupport {
private Point point;
private List references;
public Point getPoint() {
return point;
}
public void setPoint(Point point) {
this.point = point;
}
public List getReferences() {
return references;
}
public void setReferences(List references) {
this.references = references;
}
public String execute() {
if(references == null) {
System.out.println("references is null");
} else {
System.out.println("references length is:" + references.size());
for(Object s: references) {
System.out.println("" + s);
}
}
return SUCCESS;
}
}
对象类型List转换(key-value pair 方式)
// Person 类型
package org.apache.struts2.showcase.conversion;
import java.io.Serializable;
/**
*
*/
public class Person implements Serializable {
private String name;
private Integer age;
public void setName(String name) { this.name = name; }
public String getName() { return this.name; }
public void setAge(Integer age) { this.age = age; }
public Integer getAge() { return this.age; }
}
// PersionAction 类型
package org.apache.struts2.showcase.conversion;
import java.util.List;
import com.opensymphony.xwork2.ActionSupport;
/**
*
*/
public class PersonAction extends ActionSupport {
private List persons;
public List getPersons() { return persons; }
public void setPersons(List persons) { this.persons = persons; }
public String input() throws Exception {
return SUCCESS;
}
public String submit() throws Exception {
return SUCCESS;
}
}
// PersonAction转化配置文件PersonAction-conversion.properties
# PersonAction中persons属性(List类型)中元素的类型
Element_persons=org.apache.struts2.showcase.conversion.Person
// JSP部分代码
<s:iterator value="new int[3]" status="stat">
<s:textfield label="%{'Person '+#stat.index+' Name'}"
name="%{'persons['+#stat.index+'].name'}" />
<s:textfield label="%{'Person '+#stat.index+' Age'}"
name="%{'persons['+#stat.index+'].age'}" />
</s:iterator>
其中stat记录了当前循环的信息,其中stat.index表示当前循环的下标。
所以上述代码会生成如下的代码:
<s:textfield label="Person 1 Name"
name="persons[0].name" />
<s:textfield label="Person 1 Age"
name="persons[0].age" />
<s:textfield label="Person 2 Name"
name="persons[1].name" />
<s:textfield label="Person 2 Age"
name="persons[1].age" />
<s:textfield label="Person 3 Name"
name="persons[2].name" />
<s:textfield label="Person 3 Age"
name="persons[2].age" />
对象类型List转换(value 方式)
// Address 类型
package org.apache.struts2.showcase.conversion;
/**
* @version $Date: 2006-11-23 12:31:52 -0500 (Thu, 23 Nov 2006) $ $Id: Address.java 478625 2006-11-23 17:31:52Z wsmoak $
*/
public class Address {
private String id;
private String address;
public String getId() { return id; }
public void setId(String id) { this.id = id; }
public String getAddress() { return address; }
public void setAddress(String address) { this.address = address; }
}
// AddressAction 类型
package org.apache.struts2.showcase.conversion;
import java.util.LinkedHashSet;
import java.util.Set;
import com.opensymphony.xwork2.ActionSupport;
/**
* @version $Date: 2006-11-23 12:31:52 -0500 (Thu, 23 Nov 2006) $ $Id: AddressAction.java 478625 2006-11-23 17:31:52Z wsmoak $
*/
public class AddressAction extends ActionSupport {
private Set addresses = new LinkedHashSet();
public Set getAddresses() { return addresses; }
public void setAddresses(Set addresses) { this.addresses = addresses; }
public String input() throws Exception {
return SUCCESS;
}
public String submit() throws Exception {
System.out.println(addresses);
return SUCCESS;
}
}
//AddressAction转换配置文件AddressAction-conversion.properties
KeyProperty_addresses=id
Element_addresses=org.apache.struts2.showcase.conversion.Address
CreateIfNull_addresses=true
// JSP代码
<s:form action="submitAddressesInfo" namespace="/conversion">
<s:iterator value="%{new int[3]}" status="stat">
<s:textfield label="%{'Address '+#stat.index}"
name="%{'addresses(\\'id'+#stat.index+'\\').address'}" />
</s:iterator>
<s:submit />
</s:form>
上述代码会转换为:
<s:form action="submitAddressInfo" namespace="/conversion">
<s:textfield label="Address 0"
name="addresses('id0')" />
<s:textfield label="Address 1"
name="addresses('id1')" />
<s:textfield label="Address 2"
name="addresses('id2')" />
<s:submit />
</s:form>
注意两个地方:
第一,没有向服务器提交Address的id属性,那么Address的id属性是什么呢?
KeyProperty_addresses=id表示向服务器提交的内容的key部分("id0”, "id1”, "id2”)会被认定为Addredd的id。
第二,CreateIfNull_addresses=true表示及时客户端没有向服务器提交任何Address内容,服务器也会为AddressAction的addresses 建立一个长度为0的Set。
相关的一些经验
开发的过程中不要一味的使用String类型,使用String类型无论在处理的速度还是内存的使用上都不是最好的方式。一般情况下,Java的模型类(JavaBean, Action等都可以视为Java模型类,因为其中表示了模型的信息),一般情况下需要和数据库中的类型一致。这样才能保证最好的性能。
那么像java.util.Date,Integer等类型需要表示到JSP页面上的时候还是需要表示为String类型的,但是Struts2都已经帮助实现了,所以请使用具体的类型吧,不要总是使用String类型。
HTTP协议中传递的任何内容都是String类型的,所以一旦我们在服务器上需要一个非String类型的对象,例如:int或者Date,那么我们就需要在收到 HTTP请求的数据的时候,首先将String类型的数据变换为我们需要的对应类型的数据,之后再使用。这个过程就是类型转换
类型转换在Struts2中是透明的,即Struts2内置了类型转换机制。
转换原理:
以一个例子来说明如何使用Struts2内置的类型转换功能。加入我们希望用户在画面上输入一个字符形式的坐标点,例如(33,2)而我们希望在程序中得到一个Point(33, 2)的类型与之对应。
要想达到上面的功能我们需要一个名字位:ActionName-conversion.properties的文件,在文件中定义Action中的属性和画面字段之间的转换关系。例如:
point = com.jpleasure.convertor.PointConverter
也就是说画面一个叫做point的项目(input类型,name为point)提交到服务器上之后,在向Action中的point属性赋值之前需要使用 PointConverter将字符串转换为Point类,在Action中的point属性向画面显示的时候需要使用PointConverter将 Point类转换为字符串类型。
其中PointConverter需要实现ognl.TypeConverter接口。TypeConverter有两个接口,一个负责将字符串转变为对象类型,另一个负责将对象类型转换为字符串类型,分别对应着内容的提交和显示。
有些时候我们希望所有的Point类在默认的情况下使用PointConverter来转换,这时候我们需要定义全局的Converter类。这可以在xwork-conversion.properties文件中定义,例如:
com.jpleasure.Point = com.jpleasure.convertor.PointConverter
在Struts2中提供了一个TypeConverter接口的默认实现:
org.apache.struts2.action.util.StrutsTypeConverter
这个类有两个默认的抽象转换方法和performFallbackConversion,performFallbackConversion方法负责处理类型转换出错的处理。
在自定义TypeConverter的时候,可以实现TypeConverter接口,之后编写TypeConverter的转换方法,也可以从 StrutsTypeConverter继承而来,StrutsTypeConverter本身实现了TypeConverter接口,并且实现了基本的转换方法。
内建的转换:
Struts2内建了对以下类型的转换的支持:
String
boolean / Boolean
char / Character
int / Integer, float / Float, long / Long, double / Double
dates - 使用HTTP 请求对应地域(Locale)的SHORT形式转换字符串和日期类型。
arrays -每一个字符串内容可以被转换为不同的对象
collections - 转换为Collection类型,默认为ArrayList类型,其中包含String类型。
对于Array类型和Collection类型,需要对其中的每一个元素进行单独的转换。
自定义TypeConverter:
使用如下的代码自定义需要的TypeConverter
public class MyConverter extends StrutsTypeConverter {
public Object convertFromString(Map context, String[] values, Class toClass) {
.....
}
public String convertToString(Map context, Object o) {
.....
}
}
为了让Struts2框架发现类型转换的错误,需要在出错的情况下在上述的两个方法中抛出XWorkException或者TypeConversionException。
我们使用一个例子来展现如何实现TypeConvertor类型:
// Point 类
package com.jpleasure.conversion;
/**
* Created by IntelliJ IDEA.
* User: ma.zhao@dl.cn
* Date: 2007/09/04
* Time: 12:33:43
* To change this template use File | Settings | File Templates.
*/
public class Point {
private int x;
private int y;
public Point() {
}
public Point(int x, int y) {
this.x = x;
this.y = y;
}
public int getX() {
return x;
}
public void setX(int x) {
this.x = x;
}
public int getY() {
return y;
}
public void setY(int y) {
this.y = y;
}
public String toString() {
StringBuffer sb = new StringBuffer("Point(");
sb.append(x).append(", ").append(y).append(")");
return sb.toString();
}
}
// PointConvertor 类
package com.jpleasure.conversion;
import org.apache.struts2.util.StrutsTypeConverter;
import java.util.Map;
/**
* Created by IntelliJ IDEA.
* User: ma.zhao@dl.cn
* Date: 2007/09/04
* Time: 12:34:18
* To change this template use File | Settings | File Templates.
*/
public class PointConvertor extends StrutsTypeConverter {
// 从字符串转换为对象的方法。
public Object convertFromString(Map map, String[] strings, Class aClass) {
if (strings.length > 0) {
String pointStr = strings[0];
String[] pointStrArray = pointStr.split(",");
if (pointStrArray.length == 2) {
Point p = new Point();
p.setX(Integer.parseInt(pointStrArray[0]));
p.setY(Integer.parseInt(pointStrArray[1]));
return p;
} else {
return null;
}
} else {
return null;
}
}
// 从对象转换为字符串的方法。
public String convertToString(Map map, Object o) {
if (o instanceof Point) {
return o.toString();
} else {
return "";
}
}
}
// 测试用PointAction类
package com.jpleasure.action;
import com.jpleasure.conversion.Point;
import com.opensymphony.xwork2.ActionSupport;
/**
* Created by IntelliJ IDEA.
* User: ma.zhao@dl.cn
* Date: 2007/09/04
* Time: 12:45:11
* To change this template use File | Settings | File Templates.
*/
public class PointAction extends ActionSupport {
private Point point;
public Point getPoint() {
return point;
}
public void setPoint(Point point) {
this.point = point;
}
public String execute() {
return SUCCESS;
}
}
// JSP文件
<%--
Created by IntelliJ IDEA.
User: ma.zhao@dl.cn
Date: 2007/09/04
Time: 12:47:40
To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%@ taglib prefix="s" uri="/struts-tags" %>
<html>
<head><title>Point Page</title></head>
<body>
<s:form action="point" namespace="/point" method="post">
<s:textfield name="point"/>
<s:property value="point"/>
<s:submit/>
</s:form>
</body>
</html>
// PointAction配置文件类。
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE struts PUBLIC
"-//Apache Software Foundation//DTD Struts Configuration 2.0//EN"
"http://struts.apache.org/dtds/struts-2.0.dtd">
<struts>
<package name="point" namespace="/point" extends="struts-default">
<action name="point" class="com.jpleasure.action.PointAction">
<result>/point/Point.jsp</result>
<!-- 定义input的result是为了处理转换出错的情况,在输入格式不正确的情况下转移到这个画面 -->
<result name="input">/point/Point.jsp</result>
</action>
<!-- Add actions here -->
</package>
</struts>
复杂的类型转换:
(1)处理Null值
有些时候我们会被NullPointerException搞的焦头烂额,为什么系统不能为我们定义了但是没有初始化的对象建立一个空的Object的引用呢?Struts2有这个功能,但是在默认情况下Struts2关闭了这个功能,要想开启这个功能,需要在ParameterInterceptor开始处理参数之前在ValueStack中将一个值开启,这个值是:InstantiatingNullHandler.CREATE_NULL_OBJECTS。
在Java代码中InstantiatingNullHandler.CREATE_NULL_OBJECTS的值是:xwork.NullHandler.createNullObjects
创建空值对象的规则为:
* 如果属性声明为Collection或List, 将返回一个ArrayList并赋值给空引用.
* 如果属性声明为Map, 将返回一个HashMap并赋值给空引用.
* 如果空值属性是一个带有无参构造函数的简单Bean, 将使用ObjectFactory.buildBean(java.lang.Class, java.util.Map)方法创建一个实例.
(2)Collection和Map
简单List转换
//JSP代码
<%--
Created by IntelliJ IDEA.
User: mazhao
Date: 2007/09/04
Time: 12:47:40
To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%@ taglib prefix="s" uri="/struts-tags" %>
<html>
<head><title>Point Page</title></head>
<body>
<s:form action="point" namespace="/point" method="post">
<s:textfield label="Point" name="point"/>
<s:textfield label="References" name="references"/>
<s:textfield label="References" name="references"/>
<s:textfield label="References" name="references"/>
<s:textfield label="References" name="references"/>
<s:textfield label="References" name="references"/>
<s:property value="point"/>
<s:submit/>
</s:form>
</body>
</html>
//Action代码
package com.jpleasure.action;
import com.jpleasure.conversion.Point;
import com.opensymphony.xwork2.ActionSupport;
import java.util.List;
/**
* Created by IntelliJ IDEA.
* User: ma.zhao@dl.cn
* Date: 2007/09/04
* Time: 12:45:11
* To change this template use File | Settings | File Templates.
*/
public class PointAction extends ActionSupport {
private Point point;
private List references;
public Point getPoint() {
return point;
}
public void setPoint(Point point) {
this.point = point;
}
public List getReferences() {
return references;
}
public void setReferences(List references) {
this.references = references;
}
public String execute() {
if(references == null) {
System.out.println("references is null");
} else {
System.out.println("references length is:" + references.size());
for(Object s: references) {
System.out.println("" + s);
}
}
return SUCCESS;
}
}
对象类型List转换(key-value pair 方式)
// Person 类型
package org.apache.struts2.showcase.conversion;
import java.io.Serializable;
/**
*
*/
public class Person implements Serializable {
private String name;
private Integer age;
public void setName(String name) { this.name = name; }
public String getName() { return this.name; }
public void setAge(Integer age) { this.age = age; }
public Integer getAge() { return this.age; }
}
// PersionAction 类型
package org.apache.struts2.showcase.conversion;
import java.util.List;
import com.opensymphony.xwork2.ActionSupport;
/**
*
*/
public class PersonAction extends ActionSupport {
private List persons;
public List getPersons() { return persons; }
public void setPersons(List persons) { this.persons = persons; }
public String input() throws Exception {
return SUCCESS;
}
public String submit() throws Exception {
return SUCCESS;
}
}
// PersonAction转化配置文件PersonAction-conversion.properties
# PersonAction中persons属性(List类型)中元素的类型
Element_persons=org.apache.struts2.showcase.conversion.Person
// JSP部分代码
<s:iterator value="new int[3]" status="stat">
<s:textfield label="%{'Person '+#stat.index+' Name'}"
name="%{'persons['+#stat.index+'].name'}" />
<s:textfield label="%{'Person '+#stat.index+' Age'}"
name="%{'persons['+#stat.index+'].age'}" />
</s:iterator>
其中stat记录了当前循环的信息,其中stat.index表示当前循环的下标。
所以上述代码会生成如下的代码:
<s:textfield label="Person 1 Name"
name="persons[0].name" />
<s:textfield label="Person 1 Age"
name="persons[0].age" />
<s:textfield label="Person 2 Name"
name="persons[1].name" />
<s:textfield label="Person 2 Age"
name="persons[1].age" />
<s:textfield label="Person 3 Name"
name="persons[2].name" />
<s:textfield label="Person 3 Age"
name="persons[2].age" />
对象类型List转换(value 方式)
// Address 类型
package org.apache.struts2.showcase.conversion;
/**
* @version $Date: 2006-11-23 12:31:52 -0500 (Thu, 23 Nov 2006) $ $Id: Address.java 478625 2006-11-23 17:31:52Z wsmoak $
*/
public class Address {
private String id;
private String address;
public String getId() { return id; }
public void setId(String id) { this.id = id; }
public String getAddress() { return address; }
public void setAddress(String address) { this.address = address; }
}
// AddressAction 类型
package org.apache.struts2.showcase.conversion;
import java.util.LinkedHashSet;
import java.util.Set;
import com.opensymphony.xwork2.ActionSupport;
/**
* @version $Date: 2006-11-23 12:31:52 -0500 (Thu, 23 Nov 2006) $ $Id: AddressAction.java 478625 2006-11-23 17:31:52Z wsmoak $
*/
public class AddressAction extends ActionSupport {
private Set addresses = new LinkedHashSet();
public Set getAddresses() { return addresses; }
public void setAddresses(Set addresses) { this.addresses = addresses; }
public String input() throws Exception {
return SUCCESS;
}
public String submit() throws Exception {
System.out.println(addresses);
return SUCCESS;
}
}
//AddressAction转换配置文件AddressAction-conversion.properties
KeyProperty_addresses=id
Element_addresses=org.apache.struts2.showcase.conversion.Address
CreateIfNull_addresses=true
// JSP代码
<s:form action="submitAddressesInfo" namespace="/conversion">
<s:iterator value="%{new int[3]}" status="stat">
<s:textfield label="%{'Address '+#stat.index}"
name="%{'addresses(\\'id'+#stat.index+'\\').address'}" />
</s:iterator>
<s:submit />
</s:form>
上述代码会转换为:
<s:form action="submitAddressInfo" namespace="/conversion">
<s:textfield label="Address 0"
name="addresses('id0')" />
<s:textfield label="Address 1"
name="addresses('id1')" />
<s:textfield label="Address 2"
name="addresses('id2')" />
<s:submit />
</s:form>
注意两个地方:
第一,没有向服务器提交Address的id属性,那么Address的id属性是什么呢?
KeyProperty_addresses=id表示向服务器提交的内容的key部分("id0”, "id1”, "id2”)会被认定为Addredd的id。
第二,CreateIfNull_addresses=true表示及时客户端没有向服务器提交任何Address内容,服务器也会为AddressAction的addresses 建立一个长度为0的Set。
相关的一些经验
开发的过程中不要一味的使用String类型,使用String类型无论在处理的速度还是内存的使用上都不是最好的方式。一般情况下,Java的模型类(JavaBean, Action等都可以视为Java模型类,因为其中表示了模型的信息),一般情况下需要和数据库中的类型一致。这样才能保证最好的性能。
那么像java.util.Date,Integer等类型需要表示到JSP页面上的时候还是需要表示为String类型的,但是Struts2都已经帮助实现了,所以请使用具体的类型吧,不要总是使用String类型。
发表评论
-
struts logic
2008-01-24 18:32 2059原文地址:http://cr123321.blog.sohu. ... -
struts1 之 role
2008-01-24 18:03 1312<logic:present>的role属性 :是 ... -
struts2,struts1,jsp实现国际化的方法示例(原创)
2008-01-22 14:37 5151struts2的实现方法 LangSelector.jsp&l ... -
Struts1的国际化处理
2008-01-22 10:32 6488Struts 国际化处理一 一 ... -
资源文件查找顺序
2008-01-21 10:12 1225资源文件查找顺序之所 ... -
struts2常见问题
2008-01-10 19:00 1428这两天重新开始学习struts2。遇到了一些问题,总结一下先。 ... -
struts2的struts.properties配置文件详解
2008-01-10 18:59 1190struts2的struts.properties配置文件详解 ... -
struts2.0中struts.xml配置文件详解
2008-01-10 18:58 5087<!DOCTYPE struts PUBLIC &quo ... -
struts2 strus.xml中result类型及含义
2008-01-10 18:55 20116一个提交到服务器的处理通常可以分为两个阶段,第一个阶段查询服务 ... -
Struts2.0下的客户端验证
2008-01-10 18:43 2506Struts2.0 默认提供了 simpl ... -
struts2 学习笔记
2008-01-10 16:54 1405struts2 中文件的命名规则:1、资源文件也使用规则命名, ...
相关推荐
类以及org.apache.struts2.ServletActionContext类,具体的方法如下所示。 获得request对象: A . HttpServletRequest request = ServletActionContext.getRequest (); B.ActionContext ct= ActionContext....
struts2.1.6 convertion插件(即注释方式配置)的helloworld 默认调用index()方法 文档说明用struts.xml中标签设置值,好象不用也行 rest插件例子 默认调用 create()方法 struts2.1.6 vistor校验例子 都是我测试例子,...
Struts是一个开源的Java EE框架,它主要用于构建基于MVC...每个示例都可以独立运行,这有助于你在实践中理解每个概念,并加深对Struts 2框架的整体把握。对于想要深入学习Struts 2的开发者来说,这是一个宝贵的资源。
本程序将'风机信息.txt'中的风机位置(西安1980/北京1954坐标系)转换为经纬度坐标系。 风机参考经纬度.txt'存储了部分的风机的经纬度信息,可以用作转换的基准。
2. PT100和PT1000: 这两种传感器基于铂的电阻温度依赖性。PT100在0°C时的电阻为100欧姆,而PT1000在相同条件下为1000欧姆。它们广泛应用于工业自动化、医疗设备和实验室测量中,因为它们具有高精度和良好的线性...
标题中的"GIMMS 3G V1.0 Convertion for hdf"指的是一个转换工具,用于将GIMMS(Global Inventory Modeling and Mapping Studies)3G版本的第1阶段数据从HDF(Hierarchical Data Format)格式转化为nc4(NetCDF-4)...
标题中的"GIMMS 3g convertion"指的是一个专门针对GIMMS(Global Inventory Modeling and Mapping Studies)3g数据集的转换工具。GIMMS是一个长期的植被指数数据集,主要用于全球植被变化的研究,其中3g版本是其更新...
标题中的“Convertion program from Matlab to C++ using Armadillo”指的是一个项目或教程,它指导用户如何将用Matlab编写的代码转换为C++语言,并利用Armadillo库进行数值计算。Armadillo是一个开源的C++库,设计...
**2. 修订内容** 2004年11月5日发布的修订案主要包括以下几点: - **分支电路保护**: 对自我保护组合电机控制器的分支电路保护提出了新的要求。 - **标记与安装信息**: 允许通过电子只读数字媒体格式(如CD-ROM、...
##### 2. __stdcall - **定义**:参数同样是从右至左压栈,但是栈空间的清理由被调用的函数完成。 - **特点**: - 函数名称会根据参数的数量进行修饰,通常格式为`_函数名@数字`。 - 由于被调用函数负责清理栈,...
2. **XML解析** 在Java中,我们可以使用DOM(Document Object Model)、SAX(Simple API for XML)或StAX(Streaming API for XML)等解析器来读取和解析XML文档。DOM一次性加载整个XML文件,适合小型文件;SAX和...
Java虽然通常用于构建大型应用程序,但通过Java Micro Edition(Java ME),它也可以应用于嵌入式系统,包括单片机。 在Java编程中实现温度转换,我们可以创建一个类,例如`TemperatureConverter`,它包含两个方法...
2. **赞助单位**:本书由IEEE电路与系统学会赞助,该学会是IEEE的一个专业分会,专注于电路与系统领域的研究和发展。 3. **技术评审人员**:书中列出了多位技术评审人员,他们分别来自学术界和工业界,为书籍的内容...
地心惯性坐标系到地理坐标系;地理坐标系到地球坐标系等转换,共计8个程序
《Little Shape Conversion——开源软件在地理信息系统中的应用》 在当今的地理信息系统(GIS)领域,数据格式的互换和转换是一项重要的任务。各种各样的数据格式满足了不同应用场景的需求,但同时也带来了兼容性的...
模板可以包含预定义的占位符,例如 `${author}` (作者)、`${date}` (日期) 和 `${package_name}` (包名) 等,这些占位符在插入注释时会根据实际信息自动填充。 **配置代码模板** 要配置Eclipse的代码模板,可以...
然后,他们需要运行这两个脚本之一,提供必要的配置信息,如诺基亚手机的电子邮件地址(许多诺基亚手机支持通过电子邮件接收vCard),以及可能的任何其他特定于设备的设置。脚本会自动打包并发送vCards到指定的...
usage: convertion vector(double) to arff(weka) type code.
总结一下,Rust的类型转换主要依赖于`as`关键字、`From`、`Into`、`TryFrom`和`TryInto`特质。而操作符重载则通过定义相应的方法或实现标准库提供的trait来实现。这种设计虽然限制了灵活性,但也增强了Rust代码的可...
语言:English 在所有网站上自动将英制单位转换为公制单位 在所有网站上自动将英制单位转换为公制单位。 转换外观的示例:“距图书馆12英里”将转换为:“距图书馆12英里(19.31公里)”没有跟踪。...