189 8069 5689

如何在Struts2中自定义一个类型转换器

这篇文章主要介绍了如何在Struts2中自定义一个类型转换器,此处给大家介绍的非常详细,对大家的学习或工作具有一定的参考价值,需要的朋友可以参考下:

创新互联专注于企业网络营销推广、网站重做改版、巍山网站定制设计、自适应品牌网站建设、H5页面制作商城建设、集团公司官网建设、成都外贸网站建设公司、高端网站制作、响应式网页设计等建站业务,价格优惠性价比高,为巍山等各大城市提供网站开发制作服务。

自定义类型转换类

有这样的一个前台页面:


 用户:
 

对应Action的部分代码为:

private User user; // 这是一个复合类型
private String tip;
public void setUsers(User user)
{
 this.user = user;
}

public User getUser()
{
 return user;
}

我们希望用户在前台页面输入格式为“username|password”这样的字符串,通过自定义的类型转换器,将这样“username|password”格式的字符串转换为User类型。下面就说说如何实现自定义类型转换器。

Struts2的类型转换器实际上依然是基于OGNL框架的,在OGNL项目中有一个TypeConverter接口,这个接口就是自定义类型转换器必须实现的接口。该接口的定义代码如下:

// OGNL提供的类型转换器接口
public interface TypeConverter
{
 public Object convertValue(Map context, Object target, Member member, String propertyName, Object value, Class toType);
}

实现类型转换器必须实现上面的TypeConverter,不过上面接口里的方法太过复杂,所以OGNL项目还为该接口提供了一个实现类:DefaultTypeConverter,通常都采用扩展该类来实现自定义类型转换器。实现自定义类型转换器需要重写DefaultTypeConverter类的convertValue方法。

下面就是转换为User类实例的转换类:

public class UserConverter extends DefaultTypeConverter
{
 public Object convertValue(Map context, Object value, Class toType)
 {
 if (toType == User.class)
 {
  // 当需要将字符串向User类型转换时
  // 系统的请求参数是一个字符串数组
  String[] params = (String[])value;

  // 创建一个User实例
  User user = new User();

  // 只处理请求参数数组第一个数组元素,并将该字符串以'|'符号分割成两个字符串
  String[] userValues = params[0].split("\\|");

  // 为User实例赋值
  user.setName(userValues[0]);
  user.setPassword(userValues[1]);

  return user;
 }
 else if (toType == String.class)
 {
  // 当需要将User类型向字符串转换时
  User user = (User)value;
  return "<" + user.getName() + "|" + user.getPassword() + ">";
 }
 return null;
 }
}

convertValue方法的作用是非常简单的,该方法负责完成类型的转换,但是这种转换是双向的,根据参数toType来判断目标类型,然后我们就可以实现两个方向的转换逻辑了。

注册类型转换器

有了类型转换器是不够的,因为Struts2框架还不知道何时使用这些类型转换器,所以必须将类型转换器注册在Web应用中,Struts2框架才可以正常使用该类型转换器。

Struts2主要支持以下两种注册类型转换器的方式:

  • 注册局部类型转换器:局部类型转换器仅仅对某个Action的属性起作用

  • 注册全局类型转换器:全局类型转换器对所有Action的特定类型的属性都会起作用

下面就来分别说说以上两种注册类型转换器的方法。

局部类型转换器

Struts2允许开发者通过局部类型转换文件来指定类型转换的相关配置信息。类型转换文件就是一个普通的Properties(*.properties)文件。局部类型转换文件的文件名应为ActionName-conversion.properties形式,其中ActionName是需要使用该类型转换文件的Action名,后面的-conversion.properties字符串则是固定的部分。类型转换文件应该放在和Action类文件相同的位置。

说完局部类型转换文件,就接着说这个注册局部类型转换器。注册局部类型转换器只需要在局部类型转换文件中增加以下一行配置即可:

=

将上面的替换成需要进行类型转换的属性、替换成类型转换器的实现类即可。对于上面实现的UserConverter类,需要在局部类型转换文件中这样配置:

# 指定user属性需要使用UserConverter类来完成类型转换
user=com.jellythink.practise.UserConverter

全局类型转换器

局部类型转换器的局限性太明显了,它只能对指定Action、指定属性起作用。但是,如果应用中有多个Action都包含了User类型的属性,或者一个Action中包含了多个User类型的属性,使用全局类型转换器将更合适。

全局类型转换器不是对指定Action的指定属性起作用,而是对指定类型起作用。比如对所有类型为com.jellythink.practise.User类型的属性起作用。

注册全局类型转换器应该提供一个xwork-conversion.properties文件,该文件就是全局类型转换文件,需要将该文件直接放在Web应用的WEB-INF/classes路径下即可。

全局类型转换文件内容由多项=项组成,将propType替换成需要进行类型转换的类型,将ConvertClass替换成类型转换器的实现类即可。对于上面实现的UserConverter类,需要在全局类型转换文件中这样配置:

com.jellythink.practise.User=com.jellythink.practise.UserConverter

“局部”VS“全局”

局部类型转换只能对指定Action的指定属性进行转换,不管该Action的该属性是数组也好,是集合类型也罢,该转换器的转换方法对该属性只转换一次。如果某个Action有个List类型的属性users,那么局部类型转换器将只调用一次convertValue()方法,该方法把users请求参数一次性地转换为一个List集合对象。

全局类型转换器会对所有Action的特定类型进行转换,如果一个Action的某个属性是数组或集合类型,而数组或集合元素是需要该转换器转换的方法,那么全局类型转换器将不是对该集合属性整体进行转换,而是对该集合属性的每个元素进行转换,也就是说,当该属性是一个数组或集合时,该数组或集合中包含几个该类型的元素,那么就会调用convertValue()方法几次。

熟悉二者的区别以后,在以后工作中就的多多注意了;特别是数组和集合元素进行转换时的区别。

基于Struts2的自定义类型转换器

上面介绍了通过继承DefaultTypeConverter类,在一个convertValue方法中,通过判断toType参数来判断转换的方向,然后分别实现不同转换方向的转换逻辑。而在Struts2框架中,为了简化类型转换器的实现,特别提供了一个StrutsTypeConverter抽象类,该类是DefaultTypeConverter类的子类。它已经实现了DefaultTypeConverter类的convertValue方法;实现该方法时,它将以前在convertValue方法中通过判断toType参数的方式来实现两个不同方向的转换变成了调用以下两个不同的方法:

  • 当把字符串转换成复合类型时,调用convertFromString抽象方法

  • 当把复合类型转换成字符串时,调用convertToString抽象方法

而我们需要做的就是继承StrutsTypeConverter抽象类,并且实现convertFromString和convertToString这两个抽象方法。

修改后的代码如下:

public class UserConverter extends StrutsTypeConverter
{
 public Object convertFromString(Map context, String[] values, Class toClass)
 {
  User user = new User();
  String[] userValues = values[0].split("\\|");
  user.setName(userValues[0]);
  user.setPassword(userValues[1]);
  return user;
 }

 public String convertToString(Map context, Object o)
 {
  // 当需要将User类型向字符串转换时
  User user = (User)o;
  return "<" + user.getName() + "|" + user.getPassword() + ">";
 }
}

到此这篇关于如何在Struts2中自定义一个类型转换器的文章就介绍到这了,更多相关的内容请搜索创新互联以前的文章或继续浏览下面的相关文章希望大家以后多多支持创新互联!


分享文章:如何在Struts2中自定义一个类型转换器
标题URL:http://cdxtjz.cn/article/pioscd.html

其他资讯