温馨提示×

温馨提示×

您好,登录后才能下订单哦!

密码登录×
登录注册×
其他方式登录
点击 登录注册 即表示同意《亿速云用户服务条款》

Spring Boot中怎么用Convert接口实现类型转换器

发布时间:2021-08-14 14:45:55 来源:亿速云 阅读:1172 作者:chen 栏目:开发技术

本篇内容主要讲解“Spring Boot中怎么用Convert接口实现类型转换器”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“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<S, T> {       
                  T convert(S source);     
              }

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

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

              添加依赖

              添加spring-boot-starter-web依赖

              <dependency>
                          <groupId>org.springframework.boot</groupId>
                          <artifactId>spring-boot-starter-web</artifactId>
                      </dependency>

              实体类

              1.User类
              public class User {
                private long  id;
                //用户名
                private String name;
                //出生日期
                private Date birth;
                //关联用户
                private User linkUser;
                //喜欢的文章
                private List<Article> 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<String,Date> {
                //日期格式
               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<String,User> {
                @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<String, List<Article>> {
               ObjectMapper objectMapper=new ObjectMapper();
                @Override
                public List<Article> convert(String s) {
                  List<Article> list=null;
                  try {
                     list=objectMapper.readValue(s, new TypeReference<List<Article>>() {
                    });
                  } 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下进行发送数据,会出现请求参数异常错误。

              Spring Boot中怎么用Convert接口实现类型转换器

              测试结果:

              Spring Boot中怎么用Convert接口实现类型转换器

              Converter使用及其原理

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

              配置文件中对Converter的引用

              <!-- 属性编辑器 -->
                  <bean id="conversionService"
                      class="org.springframework.format.support.FormattingConversionServiceFactoryBean">
                      <property name="converters">
                          <list>
                              <bean class="com.xxx.common.converter.StringTrimConverter" />
                              <bean class="com.xxx.common.converter.DateConverter" />
                              <bean class="com.xxx.common.converter.DatetimeConverter" />
                          </list>
                      </property>
                  </bean>
              <mvc:annotation-driven conversion-service="conversionService">

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

              以字符串去空为例

              import org.springframework.core.convert.converter.Converter;
              /**
               * 去除前后空格
               * @author 
               *
               */
              public class StringTrimConverter implements Converter<String, String> {
                  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.
               *
               * <p>Implementations may additionally implement {@link ConditionalConverter}.
               *
               * @author Keith Donald
               * @since 3.0
               * @see ConditionalConverter
               * @param <S> The source type
               * @param <T> The target type
               */
              public interface Converter<S, T> {
                  /**
                   * 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
              <bean id="conversionService"
                      class="org.springframework.format.support.FormattingConversionServiceFactoryBean">

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

              * <p>Like all {@code FactoryBean} implementations, this class is suitable for
               * use when configuring a Spring application context using Spring {@code <beans>}
               * 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<FormattingConversionService>, EmbeddedValueResolverAware, InitializingBean {
                  private Set<?> converters;
                  private Set<?> formatters;
                  private Set<FormatterRegistrar> 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);
                      ConversionServiceFactory.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");
                              }
                          }
                      }
                  }

              到此,相信大家对“Spring Boot中怎么用Convert接口实现类型转换器”有了更深的了解,不妨来实际操作一番吧!这里是亿速云网站,更多相关内容可以进入相关频道进行查询,关注我们,继续学习!

              向AI问一下细节

              免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。

              AI