全网整合营销服务商

电脑端+手机端+微信端=数据同步管理

免费咨询热线:400-708-3566

springMVC4之强大类型转换器实例解析

我们以自定义格式转换器的实现思路,来理解新架构的类型转换器的使用方法,同时在实际开发中,我们可能会有自己的格式转换需求,这个时候我们也可以通过自定义格式转换器来完成这些个性化需求。

自定义格式转换器

完成自定义转换器需要实现以下三个中的任意一个接口:Convertor<S,T>、GenericConvertor或ConvertorFacoty。下面我们对这些接口进行逐一分析:

1. Convertor<S,T>

这是最为简单的一个接口,定义了从源类到目标类的转换方法。该接口的定义如下

public interface ConverterFactory<S, R> {
  //将S类型的对象转换为T类型,R为目标类型T的基类
  <T extends R> Converter<S, T> getConverter(Class<T> targetType);
}

2. GenericConvertor

GenericConvertor会根据源类对象及目标类对象所在宿主类的上下文信息进行类型转换工作,该接口的定义如下:

public interface GenericConverter {

  //ConvertiblePair包含了源类型和目标类型,它的定义在下面
  Set<ConvertiblePair> getConvertibleTypes();

  //TypeDescriptor包含了需转换类型对象所在宿主类的信息,我们根据此信息,完成源到目标类型的转换
  Object convert(Object source, TypeDescriptor sourceType, TypeDescriptor targetType);


  /**
   * 内部类定义
   */
  public static final class ConvertiblePair {
    //源类型
    private final Class<?> sourceType;
    //目标类类型
    private final Class<?> targetType;

    /**
     * 创建一个源-目标对子
     */
    public ConvertiblePair(Class<?> sourceType, Class<?> targetType) {
      Assert.notNull(sourceType, "Source type must not be null");
      Assert.notNull(targetType, "Target type must not be null");
      this.sourceType = sourceType;
      this.targetType = targetType;
    }

    public Class<?> getSourceType() {
      return this.sourceType;
    }

    public Class<?> getTargetType() {
      return this.targetType;
    }
    //忽略hashCode\equals\toString等重写方法
  }
}

我们常使用其实现类接口:

public interface ConditionalGenericConverter extends GenericConverter, ConditionalConverter {
}

它除了实现GenericConverter,还实现了另一个“条件转换器”:

public interface ConditionalConverter {
  /**
   * Should the conversion from {@code sourceType} to {@code targetType} currently under
   */
  //根据源类型和目标类型所在宿主类型的上下文信息判断是否要进行类型转换
  boolean matches(TypeDescriptor sourceType, TypeDescriptor targetType);
}

在实际开发中,我们能实现此接口自定义转换器,来根据具体类型上下文来灵活配置我们的类型转换

3. ConvertorFacoty

这是一个将我们源类转换为一个目标类或其子类的”多转换器共存“接口工厂。它的定义如下:

public interface ConverterFactory<S, R> {

  //获取将源类转换为特定R类或其子类的转换器
  <T extends R> Converter<S, T> getConverter(Class<T> targetType);

}

这个接口一个常见的实现类是StringToNumberConvertor,能将String类型数据转换为Number类型或其子类:Long,Integer,Double等。

注册自定义转换器

ConversionService

ConversionService则是Spring类型转换体系的核心接口,ConversionService接口的定义如下:

package org.springframework.core.convert;

public interface ConversionService {

  //判断sourceType是否可以转换为targetType
  boolean canConvert(Class<?> sourceType, Class<?> targetType);

  //TypeDescriptor描述了转换类的各类上下文信息,在类型转换实现方法中可以根据这些信息进行灵活控制
  //比如这里通过源类和目标类的上下文信息判断是否可以进行转换
  boolean canConvert(TypeDescriptor sourceType, TypeDescriptor targetType);

  //将source转换为targetType
  <T> T convert(Object source, Class<T> targetType);

  //利用源、目标类的上下文信息,将源类型转换为目标类型
  Object convert(Object source, TypeDescriptor sourceType, TypeDescriptor targetType);

}

ConversionServiceFactoryBean

实现以上类型完成我们的自定义转换器定义后,我们还要在Spring容器中通过ConversionServiceFactoryBean注册创建后才能使用。

ConversionServiceFactoryBean创建了我们的ConversionService很多内置转换器,利用这些转换器,我们可以完成大部分常见的类型转换工作

而如果我们想使用自定义的类型转换器,可以通过ConversionServiceFactoryBean的convertor属性来注册。

实例分析1:测试Convertor

通过以上的分析,我们接下来尝试自定实现Convert

1. 自定义属性转换器

public class MyConvertor implements Converter<String, User>{

  @Override
  public User convert(String source) {//source为要转换的字符串
    String[] values = source.split(",");//根据我们的需求,用逗号来区分
    Integer id = Integer.valueOf(values[0]);
    User user = new User(id,values[1],values[2]);
    return user;
  }
}
/**********下面是我们的UserPOJO类**********/
public class User {
  public User() {
    super();
  }
  private Integer id;
  private String userName;
  private String password;
  public Integer getId() {
    return id;
  }
  public void setId(Integer id) {
    this.id = id;
  }
  public User(Integer id, String userName, String password) {
    super();
    this.id = id;
    this.userName = userName;
    this.password = password;
  }
  //忽略get和set方法
  @Override
  public String toString() {
    return "User [id=" + id + ", userName=" + userName + ", password="
        + password + "]";
  }

}

2. 注册自定义属性转换器

<!-- 通过:annotation-driven的conversion-service属性来装配我们的类型转换器 -->
<mvc:annotation-driven conversion-service="factoryBean" />
<!-- 通过ConversionServiceFactoryBean注册我们的自定义转换器 -->
<bean class="org.springframework.context.support.ConversionServiceFactoryBean" id="factoryBean" >
  <property name="converters"><!-- 在属性converters注册 -->
    <list>
      <bean class="com.mvc.convertor.MyConvertor" />
    </list>
  </property>
</bean> 

3. 配置控制器

在控制层,我们通过以下方法测试我们的转换器

@RequestMapping("convert")
public String convert(User user){
  System.out.println(user);
  return "model1";
}

4. 测试

启动服务器,在游览器中访问[项目根路径]/convert?user=11,myUserName,myPassword。
控制台会打印信息:User [id=11, userName=myUserName, password=myPassword]。即springMVC帮我们完成了字符串到User类型的转换。**这里需注意的是,我们的请求参数名”user”是和控制层方法入参变量User user像对应的,才能完成参数绑定进而转换类型

实例分析2:测试ConvertorFactory

1. 自定义类型转换器

在实例1的基础上,我们添加User的一个子类:SuperUser,作为”super”子类,它拥有了自己的专属名字,我们将字符串”11,myUserName,myPassword,myName“转换为我们的superUser对象,下面相对应的自定义转换器和POJO类

public class MySuperConvertor implements Converter<String, SuperUser>{

  @Override
  public SuperUser convert(String source) {
    String[] values = source.split(",");
    Integer id = Integer.valueOf(values[0]);
    SuperUser superUser = new SuperUser(values[3], new User(id,values[1],values[2]));
    return superUser;
  }
}
/**********下面是SuperUser POJO类*********/
package com.mvc.model;

public class SuperUser extends User {
  private String name;
  //忽略get和set方法

  public SuperUser(String name,User user) {
    super(user.getId(),user.getUserName(),user.getPassword());
    this.name = name;
  }

  public SuperUser() {
    super();
  }

  @Override
  public String toString() {
    return "SuperUser [name=" + name + ", toString()=" + super.toString()
        + "]";
  }
}

除了配置上面的转换器,还需自定义我们的转换器工厂,在转换器工厂中,我们根据目标类型是User还是其子类SuperUser来调用相应的自定义转换器:

public class MyConvertorFactory implements ConverterFactory<String, User>{

  @Override
  //T类型必须是User或其子类,Stirng是我们的转换源类
  public <T extends User> Converter<String, T> getConverter(

      Class<T> targetType) {
    if(targetType == User.class){
      return (Converter<String, T>) new MyConvertor();
    }else{
      return (Converter<String, T>) new MySuperConvertor();
    }
  }
}

2. 注册自定义属性转换器

<!-- 通过:annotation-driven的conversion-service属性来装配我们的类型转换器 -->
<mvc:annotation-driven conversion-service="factoryBean" />
<!-- 通过ConversionServiceFactoryBean注册我们的自定义转换器 -->
<bean class="org.springframework.context.support.ConversionServiceFactoryBean" id="factoryBean" >
  <property name="converters"><!-- 在属性converters注册 -->
    <list>
      <!--这里只要注册我们自定义的转换器工厂即可-->
      <bean class="com.mvc.convertor.MyConvertorFactory" />
    </list>
  </property>
</bean> 

3. 配置控制器

在实例1的基础上,我们添加一个新方法

//这是原来的
@RequestMapping("convert")
public String convert( User user){
  System.out.println(user);
  return "model1";
}
//下面是新添加的方法
@RequestMapping("convertSuper")
public String convert( SuperUser user){
  System.out.println(user);
  return "model1";
}

4. 测试

运行服务器,我们在游览器中输入:

1. root/convert?user=10,myUserName,myPassword

控制台输出:User [id=10, userName=myUserName, password=myPassword]

2. root/convertSuper?superUser=11,myUserName,myPassword,myName

控制台输出:SuperUser [name=myName, toString()=User [id=11, userName=myUserName, password=myPassword]]

我们根据入参类型,并通过ConvertFactory,完成对同一系列(某一类及其子类)的类型转换

源码下载

本篇文章测试源码可到https://github.com/jeanhao/spring的dataConvertor文件夹下下载

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持。


# springmvc类型转换器  # springmvc4类型转换器  # converter  # 类型转化  # 详解自定义SpringMVC的Http信息转换器的使用  # SpringMVC实现自定义类型转换器  # SpringMVC中日期格式的转换  # springmvc学习笔记-返回json的日期格式问题的解决方法  # 如何使用Spring MVC的消息转换器设置日期格式  # 自定义  # 子类  # 转换为  # 或其  # 自己的  # 这是  # 基础上  # 可以通过  # 的是  # 判断是否  # 器中  # 会有  # 包含了  # 在实际  # 则是  # 要在  # 这是一个  # 我们可以  # 这个时候  # 重写 


相关文章: 沈阳个人网站制作公司,哪个网站能考到沈阳事业编招聘的信息?  郑州企业网站制作公司,郑州招聘网站有哪些?  金*站制作公司有哪些,金华教育集团官网?  如何快速搭建高效香港服务器网站?  寿县云建站:智能SEO优化与多行业模板快速上线指南  西安大型网站制作公司,西安招聘网站最好的是哪个?  建站之星展会模板:智能建站与自助搭建高效解决方案  如何选择高效便捷的WAP商城建站系统?  建站之星体验版:智能建站系统+响应式设计,多端适配快速建站  如何在IIS中新建站点并解决端口绑定冲突?  建站主机SSH密钥生成步骤及常见问题解答?  建站主机助手选型指南:2025年热门推荐与高效部署技巧  网站制作的方法有哪些,如何将自己制作的网站发布到网上?  建站主机如何安装配置?新手必看操作指南  如何通过服务器快速搭建网站?完整步骤解析  孙琪峥织梦建站教程如何优化数据库安全?  如何获取PHP WAP自助建站系统源码?  建站10G流量真的够用吗?如何应对访问高峰?  上海网站制作开发公司,上海买房比较好的网站有哪些?  开心动漫网站制作软件下载,十分开心动画为何停播?  如何选择高效可靠的多用户建站源码资源?  武汉网站设计制作公司,武汉有哪些比较大的同城网站或论坛,就是里面都是武汉人的?  如何用低价快速搭建高质量网站?  如何通过虚拟主机快速搭建个人网站?  定制建站策划方案_专业建站与网站建设方案一站式指南  Swift开发中switch语句值绑定模式  百度网页制作网站有哪些,谁能告诉我百度网站是怎么联系?  如何解决ASP生成WAP建站中文乱码问题?  如何快速上传自定义模板至建站之星?  长春网站建设制作公司,长春的网络公司怎么样主要是能做网站的?  青岛网站建设如何选择本地服务器?  黑客入侵网站服务器的常见手法有哪些?  建站主机CVM配置优化、SEO策略与性能提升指南  如何在西部数码注册域名并快速搭建网站?  如何通过PHP快速构建高效问答网站功能?  建站主机核心功能解析:服务器选择与网站搭建流程指南  小捣蛋自助建站系统:数据分析与安全设置双核驱动网站优化  如何在Golang中使用replace替换模块_指定本地或远程路径  大同网页,大同瑞慈医院官网?  如何在阿里云虚拟机上搭建网站?步骤解析与避坑指南  建站与域名管理如何高效结合?  招商网站制作流程,网站招商广告语?  如何在万网主机上快速搭建网站?  高端企业智能建站程序:SEO优化与响应式模板定制开发  北京网站制作的公司有哪些,北京白云观官方网站?  齐河建站公司:营销型网站建设与SEO优化双核驱动策略  定制建站流程解析:需求评估与SEO优化功能开发指南  猪八戒网站制作视频,开发一个猪八戒网站,大约需要多少?或者自己请程序员,需要什么程序员,多少程序员能完成?  交易网站制作流程,我想开通一个网站,注册一个交易网址,需要那些手续?  网站制作大概要多少钱一个,做一个平台网站大概多少钱? 

您的项目需求

*请认真填写需求信息,我们会在24小时内与您取得联系。