亚洲乱码中文字幕综合,中国熟女仑乱hd,亚洲精品乱拍国产一区二区三区,一本大道卡一卡二卡三乱码全集资源,又粗又黄又硬又爽的免费视频

Spring Boot中如何使用Convert接口實(shí)現(xiàn)類型轉(zhuǎn)換器

 更新時(shí)間:2021年08月14日 11:48:41   作者:Code0cean  
這篇文章主要介紹了Spring Boot中使用Convert接口實(shí)現(xiàn)類型轉(zhuǎn)換器的操作,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教

使用Convert接口實(shí)現(xiàn)類型轉(zhuǎn)換器

在Spring3中引入了一個(gè)Converter接口,它支持從一個(gè)Object轉(zhuǎn)為另一個(gè)Object。除了Converter接口之外,實(shí)現(xiàn)ConverterFactory接口和GenericConverter接口也可以實(shí)現(xiàn)我們自己的類型轉(zhuǎn)換邏輯。

Converter接口

首先看看Converter接口的定義

public interface Converter<S, T> {       
    T convert(S source);     
} 

可以看到這個(gè)接口是使用了泛型的,S表示原類型,T表示目標(biāo)類型,然后里面定義了一個(gè)convert方法,將原類型對(duì)象作為參數(shù)傳入進(jìn)行轉(zhuǎn)換之后返回目標(biāo)類型對(duì)象。

下面在Spring Boot中使用Converter接口來(lái)實(shí)現(xiàn)將String類型分別轉(zhuǎn)換為Data,自定義對(duì)象和List<自定義對(duì)象>。

添加依賴

添加spring-boot-starter-web依賴

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

實(shí)體類

1.User類

public class User {
  private long  id;
  //用戶名
  private String name;
  //出生日期
  private Date birth;
  //關(guān)聯(lián)用戶
  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方法
}

配置類型轉(zhuǎn)化器

下面三個(gè)類都需要添加@Component注解,否則不能生效。并實(shí)現(xiàn)Spring提供的org.springframework.core.convert.converter.Converter接口,重寫其中的convert()方法 ,方法中寫自己的轉(zhuǎn)換邏輯。

1.定義全局日期轉(zhuǎn)換器

@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 {
        //解析參數(shù)
        Date date=sdf.parse(s);
        return date;
      } catch (ParseException e) {
        e.printStackTrace();
      }
    }
    return null;
  }
}

2.定義全局對(duì)象轉(zhuǎn)換器

這里使用Jackson的ObjectMapper類的readValue()函數(shù)實(shí)現(xiàn)將Json字符串反序列化為Java對(duì)象

@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類型轉(zhuǎn)換器

這里使用Jackson的ObjectMapper類的readValue()函數(shù)實(shí)現(xiàn)將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設(shè)置返回?cái)?shù)據(jù)的類型為json,consumes設(shè)置提交內(nèi)容的類型為:application/x-www-form-urlencoded。

application/x-www-form-urlencoded作用:將鍵值對(duì)的參數(shù)用&連接起來(lái),如果有空格,將空格轉(zhuǎn)換為+加號(hào);有特殊符號(hào),將特殊符號(hào)轉(zhuǎn)換為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;
  }
}

測(cè)試

在Postman中進(jìn)行測(cè)試,注意以下設(shè)置:POST請(qǐng)求 -> Body -> x-www-form-urlencoded。在Body中輸入?yún)?shù)進(jìn)行測(cè)試。

因?yàn)閰?shù)中有Json類型參數(shù),如果直接使用Params下進(jìn)行發(fā)送數(shù)據(jù),會(huì)出現(xiàn)請(qǐng)求參數(shù)異常錯(cuò)誤。

在這里插入圖片描述

測(cè)試結(jié)果:

在這里插入圖片描述

Converter使用及其原理

在Spring MVC開發(fā)中,我們可以很方便的使用Converter來(lái)實(shí)現(xiàn)對(duì)請(qǐng)求參數(shù)的處理,比如字符串去空,日期格式化等。

配置文件中對(duì)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) {
        //如果源字符串不為空則進(jìn)行轉(zhuǎn)換
        if(source != null){
            //去除源字符串前后空格
            source = source.trim();
            if(source.equals("")){ 
                source = null;
            }
        }
        return source;
    }
}

配置好以上內(nèi)容,即可在我們的請(qǐng)求中實(shí)現(xiàn)字符串自動(dòng)去空格。

明白使用其實(shí)很簡(jiǎn)單,我們可以看下在Spring的底層,具體是如何實(shí)現(xiàn)Converter的。我們以字符串去空的代碼為例。

以上代碼,首先實(shí)現(xiàn)了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);
}

通過(guò)JavaDoc我們可以看到,實(shí)現(xiàn)該接口,可以使我們將S類型的對(duì)象轉(zhuǎn)換為T類型。那么對(duì)應(yīng)的我們對(duì)于Date類型的轉(zhuǎn)換,就可寫為如下代碼:

public class DateConverter implements Converter
<bean id="conversionService"
        class="org.springframework.format.support.FormattingConversionServiceFactoryBean">

該類的對(duì)象,繼續(xù)查看對(duì)應(yīng)改類的源碼,以及對(duì)應(yīng)的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構(gòu)建Spring應(yīng)用。

我們查看對(duì)應(yīng)的成員變量:

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時(shí),我們主要配置了集合類的converters,該類比較重要的方法如下:

@Override
    public void afterPropertiesSet() {
        this.conversionService = new DefaultFormattingConversionService(this.embeddedValueResolver, this.registerDefaultFormatters);
        ConversionServiceFactory.registerConverters(this.converters, this.conversionService);
        registerFormatters();
    }

該方法實(shí)現(xiàn)了對(duì)conversionService中增減我們對(duì)應(yīng)的格式化器。

在Spring啟動(dòng)時(shí),注冊(cè)轉(zhuǎn)換器 時(shí)會(huì)進(jìn)入afterPropertiesSet 方法。在該方法中,我們可以看到Spring以HashSet來(lái)存儲(chǔ)對(duì)應(yīng)的converters。在ConversionServiceFactory中,判斷不同的轉(zhuǎn)換器,并進(jìn)行注冊(cè)。

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");
                }
            }
        }
    }

以上為個(gè)人經(jīng)驗(yàn),希望能給大家一個(gè)參考,也希望大家多多支持腳本之家。

相關(guān)文章

最新評(píng)論