Spring Boot中如何使用Convert接口实现类型转换器

网友投稿 272 2022-12-18

Spring Boot中如何使用Convert接口实现类型转换器

目录使用Convert接口实现类型转换器Converter接口添加依赖实体类1.User类2.Article类配置类型转化器1.定义全局日期转换器2.定义全局对象转换器3.定义全局List类型转换器控制器测试Converter使用及其原理配置文件中对Converter的引用以字符串去空为例我们查看Converter接口的源码我们查看对应的成员变量:

使用Convert接口实现类型转换器

在Spring3中引入了一个Converter接口,它支持从一个Object转为另一个Object。除了Converter接口之外,实现ConverterFactory接口和GenericConverter接口也可以实现我们自己的类型转换逻辑。

Converter接口

首先看看Converter接口的定义

public interface Converter {

T convert(S source);

}

可以看到这个接口是使用了泛型的,S表示原类型,T表示目标类型,然后里面定义了一个convert方法,将原类型对象作为参数传入进行转换之后返回目标类型对象。

下面在Spring Boot中使用Converter接口来实现将String类型分别转换为Data,自定义对象和List<自定义对象>。

添加依赖

添加spring-boot-starter-web依赖

org.springframework.boot

spring-boot-starter-web

实体类

1.User类

public class User {

private long id;

//用户名

private String name;

//出生日期

private Date birth;

//关联用户

private User linkUser;

//喜欢的文章

private List

favArticles=new ArrayList<>();

//下面省略Getter和Setter方法

2.Article类

public class Article {

//文章id

private long artId;

//文章名

private String artName;

//下面省略Getter和Setter方法

}

配置类型转化器

下面三个类都需要添加@Component注解,否则不能生效。并实现Spring提供的org.springframework.core.convert.converter.Converter接口,重写其中的convert()方法 ,方法中写自己的转换逻辑。

1.定义全局日期转换器

@Component

public class DateConvert implements Converter {

//日期格式

SimpleDateFormat sdf=new SimpleDateFormat("yyyy-MM-dd");

@Override

public Date convert(String s) {

if (s!=null&&!"".equals(s)){

try {

//解析参数

Date date=sdf.parse(s);

return date;

} catch (ParseException e) {

e.printStackTrace();

}

}

return null;

}

}

2.定义全局对象转换器

这里使用Jackson的ObjectMapper类的readValue()函数实现将json字符串反序列化为java对象

@Component

public class ObjectConvert implements Converter {

@Override

public User convert(String s) {

ObjectMapper objectMapper=new ObjectMapper();

if (s!=null&&!"".equals(s)){

try {

User user=objectMapper.readValue(s,User.class);

return user;

} catch (JsonProcessingException e) {

e.printStackTrace();

}

}

return null;

}

}

3.定义全局List类型转换器

这里使用Jackson的ObjectMapper类的readValue()函数实现将Json字符串反序列化为 List

@Component

public class StringToListController implements Converter> {

ObjectMapper objectMapper=new ObjectMapper();

@Override

public List

convert(String s) {

List

list=null;

try {

list=objectMapper.readValue(s, new TypeReference() {

});

} catch (JsonProcessingException e) {

e.printStackTrace();

}

return list;

}

}

控制器

这里注意使用produces设置返回数据的类型为json,consumes设置提交内容的类型为:application/x-www-form-urlencoded。

application/x-www-form-urlencoded作用:将键值对的参数用&连接起来,如果有空格,将空格转换为+加号;有特殊符号,将特殊符号转换为ASCII HEX值。

@RestController

public class HelloController {

@GetMapping("hello")

public Date getDate(Date birth){

System.out.println(birth);

return birth;

}

@PostMapping(value="showUser",produces="application/json",

consumes = "application/x-www-form-urlencoded")

public User showUser(User user){

return user;

}

}

测试

在Postman中进行测试,注意以下设置:POST请求 -> Body -> x-www-form-urlencoded。在Body中输入参数进行测试。

因为参数中有Json类型参数,如果直接使用Params下进行发送数据,会出http://现请求参数异常错误。

测试结果:

Converter使用及其原理

在Spring MVC开发中,我们可以很方便的使用Converter来实现对请求参数的处理,比如字符串去空,日期格式化等。

配置文件中对Converter的引用

class="org.springframework.format.support.FormattingConversionServiceFactoryBean">

class="org.springframework.format.support.FormattingConversionServiceFactoryBean">

如上代码,我们配置了三种类型的Converter。

以字符串去空为例

import org.springframework.core.convert.converter.Converter;

/**

* 去除前后空格

* @author

*

*/

public class StringTrimConverter implements Converter {

public String convert(String source) {

//如果源字符串不为空则进行转换

if(source != null){

//去除源字符串前后空格

source = source.trim();

if(source.equals("")){

source = null;

}

}

return source;

}

}

配置好以上内容,即可在我们的请求中实现字符串自动去空格。

明白使用其实很简单,我们可以看下在Spring的底层,具体是如何实现Converter的。我们以字符串去空的代码为例。

以上代码,首先实现了Converter接口

我们查看Converter接口的源码

/**

* A converter converts a source object of type S to a target of type T.

* Implementations of this interface are thread-safe and can be shared.

*

*

Implementations may additionally implement {@link ConditionalConverter}.

*

* @author Keith Donald

* @since 3.0

* @see ConditionalConverter

* @param The source type

* @param The target type

*/

public interface Converter {

/**

* Convert the source of type S to target type T.

* @param source the source object to convert, which must be an instance of S

* @return the converted object, which must be an instance of T

* @throws IllegalArgumentException if the source could not be converted to the desired target type

*/

T convert(S source);

}

通过JavaDoc我们可以看到,实现该接口,可以使我们将S类型的对象转换为T类型。那么对应的我们对于Date类型的转换,就可写为如下代码:

public class DateConverter implements Converter

class="org.springframework.format.support.FormattingConversionServiceFactoryBean">

该类的对象,继续查看对应改类的源码,以及对应的JavaDoc。我们可以在该类的Doc中看到如下描述:

*

Like all {@code FactoryBean} implementations, this class is suitable for

* use when configuring a Spring application context using Spring {@code }

* XML. When configuring the container with

* {@link org.springframework.context.annotation.Configuration @Configuration}

* classes, simply instantiate, configure and return the appropriate

* {@code FormattingConversionService} object from a

* {@link org.springframework.context.annotation.Bean @Bean} method.

该类适用于适用XML构建Spring应用。

我们查看对应的成员变量:

public class FormattingConversionServiceFactoryBean

implements FactoryBean, EmbeddedValueResolverAware, InitializingBean {

private Set> converters;

private Set> formatters;

private Set formatterRegistrars;

private boolean registerDefaultFormatters = true;

private StringValueResolver embeddedValueResolver;

private FormattingConversionService conversionService;

在配置XML时,我们主要配置了集合类的converters,该类比较重要的方法如下:

@Override

public void afterPropertiesSet() {

this.conversionService = new DefaultFormattingConversionService(this.embeddedValueResolver, this.registerDefaultFormatters);

Conversionhttp://ServiceFactory.registerConverters(this.converters, this.conversionService);

registerFormatters();

}

该方法实现了对conversionService中增减我们对应的格式化器。

在Spring启动时,注册转换器 时会进入afterPropertiesSet 方法。在该方法中,我们可以看到Spring以HashSet来存储对应的converters。在ConversionServiceFactory中,判断不同的转换器,并进行注册。

public static void registerConverters(Set> converters, ConverterRegistry registry) {

if (converters != null) {

for (Object converter : converters) {

if (converter instanceof GenericConverter) {

registry.addConverter((GenericConverter) converter);

}

else if (converter instanceof Converter, ?>) {

registry.addConverter((Converter, ?>) converter);

}

else if (converter instanceof ConverterFactory, ?>) {

registry.addConverterFactory((ConverterFactory, ?>) converter);

}

else {

throw new IllegalArgumentException("Each converter object must implement one of the " +

"Converter, ConverterFactory, or GenericConverter interfaces");

}

}

}

}

class="org.springframework.format.support.FormattingConversionServiceFactoryBean">

该类的对象,继续查看对应改类的源码,以及对应的JavaDoc。我们可以在该类的Doc中看到如下描述:

*

Like all {@code FactoryBean} implementations, this class is suitable for

* use when configuring a Spring application context using Spring {@code }

* XML. When configuring the container with

* {@link org.springframework.context.annotation.Configuration @Configuration}

* classes, simply instantiate, configure and return the appropriate

* {@code FormattingConversionService} object from a

* {@link org.springframework.context.annotation.Bean @Bean} method.

该类适用于适用XML构建Spring应用。

我们查看对应的成员变量:

public class FormattingConversionServiceFactoryBean

implements FactoryBean, EmbeddedValueResolverAware, InitializingBean {

private Set> converters;

private Set> formatters;

private Set formatterRegistrars;

private boolean registerDefaultFormatters = true;

private StringValueResolver embeddedValueResolver;

private FormattingConversionService conversionService;

在配置XML时,我们主要配置了集合类的converters,该类比较重要的方法如下:

@Override

public void afterPropertiesSet() {

this.conversionService = new DefaultFormattingConversionService(this.embeddedValueResolver, this.registerDefaultFormatters);

Conversionhttp://ServiceFactory.registerConverters(this.converters, this.conversionService);

registerFormatters();

}

该方法实现了对conversionService中增减我们对应的格式化器。

在Spring启动时,注册转换器 时会进入afterPropertiesSet 方法。在该方法中,我们可以看到Spring以HashSet来存储对应的converters。在ConversionServiceFactory中,判断不同的转换器,并进行注册。

public static void registerConverters(Set> converters, ConverterRegistry registry) {

if (converters != null) {

for (Object converter : converters) {

if (converter instanceof GenericConverter) {

registry.addConverter((GenericConverter) converter);

}

else if (converter instanceof Converter, ?>) {

registry.addConverter((Converter, ?>) converter);

}

else if (converter instanceof ConverterFactory, ?>) {

registry.addConverterFactory((ConverterFactory, ?>) converter);

}

else {

throw new IllegalArgumentException("Each converter object must implement one of the " +

"Converter, ConverterFactory, or GenericConverter interfaces");

}

}

}

}

版权声明:本文内容由网络用户投稿,版权归原作者所有,本站不拥有其著作权,亦不承担相应法律责任。如果您发现本站中有涉嫌抄袭或描述失实的内容,请联系我们jiasou666@gmail.com 处理,核实后本网站将在24小时内删除侵权内容。

上一篇:shiro 与 SpringMVC的整合完美示例
下一篇:Java BeanUtils工具类常用方法讲解
相关文章

 发表评论

暂时没有评论,来抢沙发吧~