zoukankan      html  css  js  c++  java
  • Spring数据转换(一)--ConversionService

    一般情况下MVC中的V在用户的客户端,而C则在服务端,当客户端向服务端提交数据时,不能再以java中的对象形式进行传输了,这时候就需要序列化和反序列化来帮助实现了。in this blog, 我们着重介绍一下springMVC中的数据转换。ConversionService是类型转换的核心接口,而ConversionServiceFactoryBean提供了一个创建ConversionService的工厂

    SpringMVC中主要有3种数据转换的实现方式,下面我将一一介绍。

    Converter<S,T>

    Spring在convert.converter中定义了3中类型的转换器接口,实现其中任何一个接口,然后将其注入到ConversionServiceFactoryBean当中就可以使用

    • Converter<S,T>,是Spring中最简单的接口,该接口中只有一个方法:T convert(S source)。该方法负责将S类型的对象转换为T类型的对象。
    • ConverterFactory<S,R> 如果希望将一种类型的对象转换为另一种类型及其子类对象,比如将String 转换为Number以及Number的子类Integer,Double等类型,就需要一系列的Converter。ConverterFactory接口的作用就是将相同系列多个Converter封装在一起,该接口中只有一个方法: Converter <S,T> getConverter(Class<T> targetType)。其中S为转换的源类型,R为目标类型的基类,T为R的子类,即为要转换目标类。
    • GenericConverter接口会根据源类对象以及目标对象的上下文信息进行类型转换。

    下面以Converter接口为例讲解其使用方法,假设定义了domain类User,其有一个Date 类型的成员变量birthday。

    public class User implements Serializable{
    	
    	private String loginname;
    	private Date birthday;
    
    	public User() {
    		super();
    	}
    
    	public String getLoginname() {
    		return loginname;
    	}
    
    	public void setLoginname(String loginname) {
    		this.loginname = loginname;
    	}
    
    	public Date getBirthday() {
    		return birthday;
    	}
    
    	public void setBirthday(Date birthday) {
    		this.birthday = birthday;
    	}
    
    	@Override
    	public String toString() {
    		return "User [loginname=" + loginname + ", birthday=" + birthday + "]";
    	}
    }
    

    当客户端向服务端Controller发送User对象时,最常用的序列化方法就是拼接成json串,那么birthDay转换为String类型才会传到服务端。而在服务端就需要正确的转换器将String类型的birthDay转换为Date类型的。这时候我们就要编写一个Converter了

    public class StringToDateConverter implements Converter<String, Date>{
    
    	// 日期类型模板:如yyyy-MM-dd,通过配置时注入
    	private String datePattern;
    	
    	public void setDatePattern(String datePattern) {
    		this.datePattern = datePattern;
    	}
    
    	// Converter<S,T>接口的类型转换方法
    	@Override
    	public Date convert(String date) {
    		try {
    			SimpleDateFormat dateFormat = new SimpleDateFormat(this.datePattern);
    			// 将日期字符串转换成Date类型返回
    			return dateFormat.parse(date);
    		} catch (Exception e) {
    			e.printStackTrace();
    			System.out.println("日期转换失败!");
    			return null;
    		}
    		
    	}
    
    }
    

    在完成Converter后就需要将其添加到Spring容器中,以备在使用时可以直接调用,我们的配置也很简单,在springmvc-config.xml中添加如下代码:

     <!-- 装配自定义的类型转换器 -->
     <mvc:annotation-driven conversion-service="conversionService"/>
    
     <bean id="conversionService" 
        	class="org.springframework.context.support.ConversionServiceFactoryBean">
        	<property name="converters">
        		<list>
        			<bean class="org.fkit.converter.StringToDateConverter"
        			p:datePattern="yyyy-MM-dd"></bean>
        		</list>
        	</property>
        </bean>
    

    从上面的例子可以看出,可以在这里配置多个Converter。如果使用mvc:annotation-driven/ SpringMVC会默认注册一个默认的ConversionService,即FormattingConversionServiceBean,可以满足大部分时候转换。

    上面介绍了3个Converter发现都是接口,而且没有任何继承关系,这使得我很纳闷,他们3个接口没有共同的父接口如何放到一个集合中呢?于是去查看ConversionServiceFactorybean的源码:

    /**
        * Configure the set of custom converter objects that should be added:
        * implementing {@link org.springframework.core.convert.converter.Converter},
        * {@link org.springframework.core.convert.converter.ConverterFactory},
        * or {@link org.springframework.core.convert.converter.GenericConverter}.
        */
    public void setConverters(Set<?> converters) {
        this.converters = converters;
    }
    

    发现其中有一个Set<?> 类型的集合,这样就可以存放多种类型的转换器了。

    在完成以上配置后,就可以在Controller中使用了,但是我们不用显示的调用,Spring会帮我们完成这件事。我们只需正常使用就可以。

    @Controller
    public class UserController{	 
    	 @RequestMapping(value="/register",method=RequestMethod.POST)
    	 public String register(
    			 @ModelAttribute User user,
    			 Model model) {
    		 logger.info(user);
    		 model.addAttribute("user", user);
    	     return "success";
    	 }
    }
    
    I am chris, and what about you?
  • 相关阅读:
    [NOI2012]美食节——费用流(带权二分图匹配)+动态加边
    mysqlsla slow-query常用用法
    [POI2000]病毒
    mysqlsla安装
    mysqldumpslow
    [学习笔记]约数
    查看MySQL数据的连接
    [学习笔记]质数
    关于ulimit -a中需要修改的两个值
    Miller-Rabin与二次探测
  • 原文地址:https://www.cnblogs.com/arax/p/8551720.html
Copyright © 2011-2022 走看看