`
jdluojing
  • 浏览: 17996 次
  • 性别: Icon_minigender_1
文章分类
社区版块
存档分类
最新评论

Struts2学习笔记(十二) 类型转换(Type Conversion)(下)

 
阅读更多

null引用处理

我们知道,我们在Action中定义属性时并没有对他们进行初始化,那么也就是Struts2在对请求参数进行类型转换时,我们的Action属性可能还是null。那么框架会自动将这些null的属性实例化一个默认的对象(在学习Parameters拦截器时已经看过源代码了):

(1)如果我们的属性声明为List(Collection)类型,那么默认会给他实例化一个ArrayList对象

(2)如果我们的属性声明为Map类型,那么默认会给他实例化一个HashMap对象

(3)如果我们的属性是一个简单的JavaBean,并且含有一个没有参数的构造器,那么Struts2会通过ObjectFactory类的buildBean方法来给他实例化一个对应的对象

自定义类型转换器

要想实现自定义类型转换器,只需我们自定义的Class实现ognl.TypeConterter接口即可。Strtus2中的DefaultTypeConverter类已经实现了这个接口,并且其子类StrutsTypeConverter对它做了更好的扩充,这是一个抽象类,需要我们继承并实现其中的两个方法。

abstract Object

convertFromString(Mapcontext,String[]values, ClasstoClass)
Converts one or more String values to the specified class.

abstract String

convertToString(Mapcontext,Objecto)
Converts the specified object to a String.

这样使得不用我们自己去判断转换的方向。 那么要实现自定义的类型转换器,选择实现StrutsTypeConverter类显得最方便。下面我们就动手自己写一个自定义类型转换器,来实现将字符串转换为User对象。

User.java

public class User {

	private String userName;
	private int age;

	public String getUserName() {
		return userName;
	}

	public void setUserName(String userName) {
		this.userName = userName;
	}

	public int getAge() {
		return age;
	}

	public void setAge(int age) {
		this.age = age;
	}

}

UserAction.java

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 {
		return SUCCESS;
	}
}

UserConverter.java

public class UserConverter extends StrutsTypeConverter {

	@Override
	public Object convertFromString(Map context, String[] values, Class toClass) {
		
		String[] input = values[0].split(":");
		if(input.length != 2){
			throw new TypeConversionException("请输入正确的格式如,zhangsan:21");
		}
		
		try {
			
			User user = new User();
			String name = input[0];
			int age = Integer.parseInt(input[1]);
			
			user.setUserName(name);
			user.setAge(age);
			
			return user;
			
		} catch (Exception e) {
			throw new TypeConversionException("请输入正确的格式如,zhangsan:21");
		}
		
	}

	@Override
	public String convertToString(Map context, Object o) {
		
		User user = (User) o;
		String str = "Name : "+user.getUserName()+";Age : "+user.getAge();
		
		return null;
	}

}

input.jsp

<body>

<s:iftest="hasFieldErrors()">

<s:iteratorvalue="fieldErrors">

<fontcolor="#FF0000"><s:propertyvalue="value[0]"/></font><br>

</s:iterator>

</s:if>

<formaction="user.action"method="post">

user: <inputtype="text"name="user"/>

<inputtype="submit"value="submit"/>

</form>

success.jsp

<body>

${user.userName }<br/>

${user.age }

</body>]

现在代码就写完了,剩下的就是要来注册我们的类型转换器了。我们需要在Action类所在目录下新建一个”ActionClass-conversion.properties”形式的文件,并在其中为Action的属性配置类型转换器,格式为:属性名=类型转换器类全名(好包名)。例如本例中需要在UserAction类所在目录下新建一个UserAction-conversion.properties文件,内容如下:

user =action.UserConverter

测试:

提交:

定制错误消息

这里我们在表单中都是按照我们预定的格式输入,那么如果我们输入的数据并不是按照我们规定的格式,那么会是什么结果呢?我们将输入改为”zhangsan-21”,再次提交:

这样的错误消息可能并不是我们想要的,那么我们怎么去定制这些错误消息呢。还记得我们在学习Action的时候学到的关于validate方法验证失败时的错误消息定制吧。在这里我们同样可以使用这种方法。只需要在我们的ActionClass.properties文件中按照指定的格式配置就可以了:

invalid.fieldvalue.fieldName= 自定义消息

这个文件也需要和Action类放在同一目录。例如本例中我们在UserAction.properties文件中为user成员属性添加一条类型转换错误消息:

invalid.fieldvalue.user=\u8BF7\u8F93\u5165\u6B63\u786E\u7684\u683C\u5F0F\u5982\uFF0Czhangsan\:21(内容为:请输入正确的格式如,zhangsan:21)

还记得吧,消息的内容都必须是unicode编码的。

现在我们再来测试,输入”zhangsan-21”,提交:

Action的属性的自定义类型转换

除了Action的成员属性以外,我们还可以给其他类的成员变量定义自定义类型转换器。比如User类中有一个Address类型的属性,Address是我们自定义的类。那么我们可以为User类中的Address属性定义一个类型转换器。和Action一样,我们需要在这个类所在的目录下新建一个ClassName-conversion.properties的文件,其中内容定义的格式和上面讲的一样。

全局类型转换器

有时候我们定义的类(bean/model)并不只是在一个Action中会被用到,那么如果需要定义自定义类型转换器的话,如果为每个Action都创建一个ActionClass-conversion.properties来完成对该类型的转换,显得很不灵活。Strtus2还提供了全局的类型转换配置,它的配置不再是针对类的属性,而是正对类本身。我们需要在src(classpath)下新建一个名为xwork-conversion.properties的文件。文件的内容和为action属性定义类型转换器的格式相似,只不过key需要是类的全路径。例如:

bean.User = action.UserConverter

这样我们在多个Action中使用该类型的属性时就可以不用在一一的配置类型转换器了。

关于ListMap类型的类型转换

在上一篇中我们讨论过如何让Struts2来完成List/Map类型的属性的自动类型转换,但是条件是List/Map中的对象类型必须是Struts2内建类型转换器能够完成转换的类型,那么如果List/Map中的对象是我们自定义的数据类型,那么该怎么让Struts2来完成转换呢。

首先我们要告诉Struts2,List/Map类型属性中元素的类型,通过在ActionClass-conversion.properties文件中使用如下形式:

List: Element_ActionList类型属性名 = List中元素类型(类的全路径)

Map:key: Key_ActionMap类型属性名 = MapKey的类型(类的全路径)

Value Element_ActionMap类型属性名 = MapValue的类型(类的全路径)

struts2的文档中只介绍了这些。我疑惑的地方就是根据文档中的介绍,我们只是告诉了Struts2集合中元素的类型,但是并没告诉Struts2如何将请求参数的String类型转换为这些指定的类型。但是我按照文档中的说法来做了,发现转换并不能成功。由于集合中元素的类型并没有包含在Action的属性中,那么肯定不能在ActionClass-conversion.properties中配置类型转换器了。那么就只有为这个类配置一个全局转换器了,配置了类型转换器之后,Map类型可成功转换。

例子代码如下:

User.java略

UserAction.java

public class UserAction extends ActionSupport {

private List<User>users;

public List<User> getUsers() {

returnusers;

}

public void setUsers(List<User> users) {

this.users = users;

}

@Override

public String execute()throws Exception {

System.out.println(users);

returnSUCCESS;

}

}

UserAction-conversion.properties

Element_users = bean.User

CreateIfNull_users=true

xwork-conversion.properties

bean.User =action.UserConverter

UserConverter.java

public class UserConverter extends StrutsTypeConverter {

	@Override
	public Object convertFromString(Map context, String[] values, Class toClass) {
		
		String[] input = values[0].split(":");
		if(input.length != 2){
			throw new TypeConversionException("请输入正确的格式如,zhangsan:21");
		}
		
		try {
			
			User user = new User();
			String name = input[0];
			int age = Integer.parseInt(input[1]);
			
			user.setUserName(name);
			user.setAge(age);
			
			return user;
			
		} catch (Exception e) {
			throw new TypeConversionException("请输入正确的格式如,zhangsan:21");
		}
		
	}

	@Override
	public String convertToString(Map context, Object o) {
		
		User user = (User) o;
		String str = "Name : "+user.getUserName()+";Age : "+user.getAge();
		
		return null;
	}

}

input.jsp

<body>

<s:iftest="hasFieldErrors()">

<s:iteratorvalue="fieldErrors">

<fontcolor="#FF0000"><s:propertyvalue="value[0]"/></font><br>

</s:iterator>

</s:if>

<formaction="user.action"method="post">

user: <inputtype="text"name="users[0]"/>

<inputtype="submit"value="submit"/>

</form>

</body>

success.jsp

<body>

${users[0].userName}<br/>

</body>

测试:



结果:


备注:我们不能将自定义的interface作为Action的属性,这是因为Struts2并不知道该给它实例化一个什么样的对象。还有就是在使用泛型的时候要注意类型擦出问题。

总结:在List/Map这个问题上不知道我理解的是否正确。如果理解的有问题还请路过的前辈指正一下啊!学了类型转换之后,觉得自定义类型转换器还真是麻烦,感觉没啥必要,我想应该没几个人将User的name和age放在一个input中吧,更何况还是需要按照指定的格式来。使用系统内建的类型转换器就好了,最多不过在表单上多做一点。不过学习一下类型转换还是对理解Struts2框架有帮助的。这里还忘了一个拦截器了,Conversion Error Interceptor,他会将从ActionContext中conversionErrors属性中的所有错误信息添加为Actin的field errors,这也正是我可以在Input页面使用hasFieldErrors等获取field error的方式来获取类型转换错误信息的原因。


分享到:
评论

相关推荐

    struts2学习笔记三(第3讲.Struts2的类型转换)

    在本篇“Struts2学习笔记三”中,我们将聚焦于Struts2的类型转换这一核心特性。类型转换在处理用户提交的数据时非常关键,它允许Struts2自动将请求参数转换为Java对象的属性。 在Struts2中,类型转换主要由`...

    struts2学习笔记四(第4讲.Struts2的类型转换续)

    在"Struts2学习笔记四(第4讲.Struts2的类型转换续)"中,我们将会深入探讨Struts2中的类型转换机制,这是一个核心特性,用于处理Action类属性与HTTP请求参数之间的数据类型转换。 在HTTP请求中,数据通常是字符串...

    struts2学习笔记

    总结起来,Struts2是一个功能丰富的Java web开发框架,它的环境搭建、类型转换、输入校验、拦截器机制、国际化支持以及与Servlet API的整合,为开发者提供了强大且灵活的工具,帮助构建高效、可维护的Web应用。学习...

    struts2简单实例(类型转换方法对比)

    局部类型转换是在Action类的属性上使用注解`@TypeConversion`来实现的。这种方式只对特定的Action属性有效。例如,如果我们有一个日期类型的属性,而用户输入的是字符串,我们可以使用注解来定义如何将字符串转换为...

    Struts2实例 国际化 类型转换 struts标签

    类型转换(Type Conversion)是Struts2的一项重要特性,它能自动将请求参数转换为Action属性的预期类型。例如,用户输入的字符串可以自动转换为整数或日期。如果Struts2内置的转换器无法满足需求,开发者还可以...

    struts2 类型转换器

    2. 如果没有找到内置转换器,Struts2会在Action类上查找注解`@ConvertProperty`或`@Conversion`,以及Action类的字段上查找注解`@ConvertType`,以获取自定义类型转换器的信息。 3. 如果注解没有提供转换器,Struts2...

    struts2数据类型转换器

    这篇博客“Struts2数据类型转换器”可能深入探讨了这个主题,虽然具体的细节无法在此给出,但我们可以根据Struts2中数据类型转换的工作原理来展开讨论。 在Java Web开发中,用户通过表单提交的数据通常是字符串形式...

    STRUTS2类型转换

    Struts2是一个流行的Java web开发框架,其核心是Action,而类型转换是Struts2处理用户输入数据的一个重要环节。Struts2内置了多种类型转换,可以将HTTP请求中的字符串数据转换为各种基本类型和复杂类型,如日期、...

    struts2自定义类型转换器

    这就是"struts2自定义类型转换器"的主题。 首先,理解Struts2的类型转换机制。当Struts2接收到HTTP请求时,它会尝试将请求参数与Action类的属性进行绑定。这个过程涉及到了类型转换,Struts2内置了一套转换器机制,...

    Struts2 自定类型转换器(三十四)

    在Struts2框架中,自定义类型转换器是开发者为了满足特定需求,对框架默认的类型转换机制进行扩展的一种方式。Struts2允许我们创建自己的转换器类来处理输入数据,确保模型对象的属性能够正确地被转换为预期的数据...

    struts2学习笔记!

    ### Struts2学习笔记 #### 一、Struts2配置文件详解 在深入理解Struts2框架之前,我们首先需要了解其核心配置文件——`struts.xml`。 **1. struts.xml配置** ```xml &lt;!DOCTYPE struts PUBLIC "-//Apache ...

    Struts2 ConverterType类型转换 案例源码

    Struts2是一个强大的MVC框架,它在处理用户请求时提供了丰富的功能,其中包括类型转换(Converter)。类型转换是Struts2框架中一个重要的特性,它允许我们把前端表单提交的数据自动转换为后端Java对象的属性。在这个...

    Struts2类型转换(一)----常规类型,自定义类型,错误处理

    Struts2是一个强大的MVC框架,它在处理Web应用程序时提供了许多便利,其中包括类型转换功能。类型转换是将用户输入的数据自动转化为服务器端处理所需的类型,这样可以避免手动转换带来的繁琐工作。本篇文章将深入...

    struts2类型转换 拦截器 校验的例子

    首先,我们来看看**类型转换(Type Conversion)**。在Struts2中,用户通过表单提交的数据通常是字符串,而服务器端处理时往往需要将其转化为其他类型,如整型、浮点型或日期等。Struts2内置了一套类型转换机制,...

    Struts2自定义类型转换

    ### Struts2自定义类型转换:深入解析与实践 #### 引言 在Web开发中,数据类型转换是一项常见的需求,特别是在用户输入的数据与后端处理的数据类型不一致时。Struts2框架提供了强大的类型转换机制,允许开发者...

    struts2类型转换

    这样,Struts2在处理该包下的Action时,会使用`MyTypeConverter`进行类型转换。 总之,Struts2的类型转换机制提高了开发效率,通过自定义转换器,我们可以灵活地处理各种数据类型,确保用户输入能够正确地转换为...

    传智播客struts2.1源代码_自定义类型转换器

    自定义类型转换器需要实现`org.apache.struts2.util.TypeConverter`接口,或者继承`org.apache.struts2.convention.converters.DefaultConversionProvider`基类,覆盖`convertValue()`方法。然后,通过在Action类或...

    struts2类型转换和国际化

    在Struts2中,类型转换和国际化是两个重要的特性,用于处理数据类型之间的转换以及多语言环境下的内容显示。 **类型转换**是Struts2处理请求参数与Action类属性之间数据类型不匹配的过程。当用户通过表单提交请求时...

Global site tag (gtag.js) - Google Analytics