環(huán)境:SpringBoot3.2.5
在Spring MVC中,數(shù)據(jù)類型的轉(zhuǎn)換、自動(dòng)綁定和格式化是一個(gè)非常強(qiáng)大的功能,Spring內(nèi)置了非常多的數(shù)據(jù)類型轉(zhuǎn)換器。如在一個(gè)HTTP請(qǐng)求中SpringMVC默認(rèn)就具備將JSON個(gè)數(shù)的數(shù)據(jù)轉(zhuǎn)換為Java對(duì)象,將一個(gè)字符串?dāng)?shù)字轉(zhuǎn)換為Number類型等等。然而,Spring的默認(rèn)數(shù)據(jù)綁定機(jī)制有時(shí)可能無法滿足特定的業(yè)務(wù)需求,比如從特定格式的字符串中解析出自定義對(duì)象的實(shí)例。為了解決這個(gè)問題,Spring允許我們自定義注解和數(shù)據(jù)格式化器,以便在請(qǐng)求參數(shù)和Java對(duì)象之間進(jìn)行自定義的轉(zhuǎn)換。
本篇文章將結(jié)合如下需求講解如何基于SpringBoot環(huán)境下自定義注解來實(shí)現(xiàn)數(shù)據(jù)的轉(zhuǎn)換。
現(xiàn)有如下接口:
@GetMapping("/user")public User getUser(User user) { return user ;}請(qǐng)求url如下:
http://localhost:9001/api/objects/user?user=666,中國在默認(rèn)情況下,Spring是無法將這里的user參數(shù)值正確的綁定到User對(duì)象。
為了盡可能的簡(jiǎn)單,期望通過在接口請(qǐng)求參數(shù)上添加一個(gè)注解就能完成數(shù)據(jù)類型的轉(zhuǎn)換及綁定。如下形式:
@GetMapping("/user")public User getUser(@UserFormat User user)Spring提供了一種基于注解驅(qū)動(dòng)的格式化,也就是上面這里看到的通過注解標(biāo)注一個(gè)參數(shù)(字段)來實(shí)現(xiàn)數(shù)據(jù)的格式化。
要實(shí)現(xiàn)基于注解驅(qū)動(dòng)的格式化,需要我們自定義類實(shí)現(xiàn)AnnotationFormatterFactory接口。該接口定義如下:
// 這里的泛型是注解類型,也就是我們要使用什么注解來標(biāo)記我們的參數(shù)(字段)public interface AnnotationFormatterFactory<A extends Annotation> { // 這個(gè)注解可以使用在什么字段上 Set<Class<?>> getFieldTypes(); // 將對(duì)象轉(zhuǎn)換為String Printer<?> getPrinter(A annotation, Class<?> fieldType); // 將字符串解析為對(duì)象 Parser<?> getParser(A annotation, Class<?> fieldType);}該接口非常的簡(jiǎn)單,主要就是如何將對(duì)象轉(zhuǎn)String,如何從String轉(zhuǎn)對(duì)象。
public class StringToUserFormatter implements AnnotationFormatterFactory<UserFormat> { @Override public Set<Class<?>> getFieldTypes() { return Set.of(User.class) ; } @Override public Printer<User> getPrinter(UserFormat annotation, Class<?> fieldType) { return (object, locale) -> object.toString() ; } @Override public Parser<User> getParser(UserFormat annotation, Class<?> fieldType) { return (text, locale) -> { Assert.hasText(text, "數(shù)據(jù)錯(cuò)誤") ; String[] s = text.split(",") ; User user = new User() ; user.setId(Long.parseLong(s[0])) ; user.setName(s[1]) ; return user ; } ; } }自定義注解:
@Retention(RetentionPolicy.RUNTIME)@Target(ElementType.PARAMETER)public static @interface UserFormat {}有了以上的工廠類后,接下來是注冊(cè)到Spring容器中。
@Componentpublic class WebDataTypeConfig implements WebMvcConfigurer { @Override public void addFormatters(FormatterRegistry registry) { registry.addFormatterForFieldAnnotation(new StringToUserFormatter()) ; }}完成以上步驟就大功告成了,接下來測(cè)試
@GetMapping("/user")public User getUser(@UserFormat User user) { return user ;}測(cè)試結(jié)果
圖片
正確的轉(zhuǎn)換為User對(duì)象。基于該注解進(jìn)行格式化不僅僅只用到接口參數(shù)上,還可以用到字段上。
public static class DTO { @UserFormat private User user ; private Integer age ;}測(cè)試接口:
// 注意,可不要改成post,然后用@RequestBody。無用反而報(bào)錯(cuò)@GetMapping("/dto")public DTO save(DTO dto) { return dto ;}測(cè)試結(jié)果
圖片
正確的輸出結(jié)果。
本文鏈接:http://m.www897cc.com/showinfo-26-91353-0.htmlSpringBoot優(yōu)雅定制接口參數(shù)格式轉(zhuǎn)換
聲明:本網(wǎng)頁內(nèi)容旨在傳播知識(shí),若有侵權(quán)等問題請(qǐng)及時(shí)與本網(wǎng)聯(lián)系,我們將在第一時(shí)間刪除處理。郵件:2376512515@qq.com
上一篇: Python中的全局變量和局部變量詳解