SpringBoot接口請(qǐng)求入?yún)⒑统鰠⒃鰪?qiáng)的五種方法
在Spring Boot , Spring Cloud中,對(duì)接口的請(qǐng)求入?yún)⒑统鰠⑦M(jìn)行自定義的序列化和反序列化增強(qiáng),通常有以下幾種方法:
1. 使用@JsonSerialize和@JsonDeserialize注解
可以在實(shí)體類的字段上使用這兩個(gè)注解來(lái)指定自定義的序列化器和反序列化器。
使用場(chǎng)景:
- 當(dāng)需要對(duì)某個(gè)特定字段進(jìn)行自定義的序列化和反序列化時(shí)。
- 當(dāng)實(shí)體類中的某些字段類型不是標(biāo)準(zhǔn)的JSON類型,需要轉(zhuǎn)換成JSON能識(shí)別的格式時(shí)。
- 需要在序列化和反序列化過(guò)程中添加自定義邏輯,如加密、解密、格式轉(zhuǎn)換等。
首先,定義自定義的序列化器和反序列化器:
public class CustomLocalDateTimeSerializer extends JsonSerializer<LocalDateTime> { @Override public void serialize(LocalDateTime value, JsonGenerator gen, SerializerProvider serializers) throws IOException { gen.writeString(value.format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"))); } } public class CustomLocalDateTimeDeserializer extends JsonDeserializer<LocalDateTime> { @Override public LocalDateTime deserialize(JsonParser p, DeserializationContext ctxt) throws IOException { return LocalDateTime.parse(p.getValueAsString(), DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")); } }
然后,在實(shí)體類中使用這些注解:
public class MyEntity { @JsonSerialize(using = CustomLocalDateTimeSerializer.class) @JsonDeserialize(using = CustomLocalDateTimeDeserializer.class) private LocalDateTime dateTime; // getters and setters }
2. 全局配置Jackson的ObjectMapper
通過(guò)配置ObjectMapper
來(lái)全局地改變序列化和反序列化的行為,可以添加自定義的模塊或配置屬性。
使用場(chǎng)景:
- 當(dāng)項(xiàng)目中多個(gè)實(shí)體類需要應(yīng)用相同的序列化和反序列化規(guī)則時(shí)。
- 需要在全局范圍內(nèi)統(tǒng)一處理日期、時(shí)間、枚舉等類型的序列化和反序列化。
- 需要對(duì)
ObjectMapper
進(jìn)行全局的配置,如設(shè)置默認(rèn)的時(shí)區(qū)、日期格式等。
創(chuàng)建一個(gè)自定義模塊,并注冊(cè)序列化器和反序列化器:
public class CustomJacksonModule extends SimpleModule { public CustomJacksonModule() { addSerializer(LocalDateTime.class, new CustomLocalDateTimeSerializer()); addDeserializer(LocalDateTime.class, new CustomLocalDateTimeDeserializer()); } }
然后,配置ObjectMapper
:
@Bean public Jackson2ObjectMapperBuilderCustomizer jsonCustomizer() { return builder -> { builder.modules(new CustomJacksonModule()); }; }
3. 使用@ControllerAdvice配合@InitBinder
要對(duì)Spring MVC的控制器進(jìn)行全局的配置,可以使用@ControllerAdvice注解。然后,在這個(gè)類中使用@InitBinder注解的方法來(lái)注冊(cè)自定義的屬性編輯器。
注意:@InitBinder主要用于處理表單數(shù)據(jù)的綁定,對(duì)于JSON數(shù)據(jù)的序列化和反序列化,它并不是最直接的方法。但如果是處理非JSON格式的請(qǐng)求體(如表單數(shù)據(jù)),則可以使用此方法。
使用場(chǎng)景(對(duì)于JSON數(shù)據(jù),更偏向于使用其他方法;對(duì)于表單數(shù)據(jù)):
- 當(dāng)需要對(duì)表單數(shù)據(jù)的綁定進(jìn)行自定義處理時(shí)。
- 當(dāng)需要在多個(gè)控制器中復(fù)用相同的表單數(shù)據(jù)綁定邏輯時(shí)。
創(chuàng)建一個(gè)自定義的屬性編輯器:
public class CustomLocalDateTimeEditor extends PropertyEditorSupport { @Override public void setAsText(String text) throws IllegalArgumentException { setValue(LocalDateTime.parse(text, DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"))); } @Override public String getAsText() { LocalDateTime value = (LocalDateTime) getValue(); return value.format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")); } }
然后,在@ControllerAdvice
類中注冊(cè)這個(gè)屬性編輯器:
@ControllerAdvice public class CustomControllerAdvice { @InitBinder public void initBinder(WebDataBinder binder) { binder.registerCustomEditor(LocalDateTime.class, new CustomLocalDateTimeEditor()); } }
4. 自定義HttpMessageConverter
可以編寫(xiě)自定義的HttpMessageConverter
來(lái)處理特定的媒體類型,并在其中實(shí)現(xiàn)自定義的序列化和反序列化邏輯。然后,將其注冊(cè)到Spring MVC的配置中。
使用場(chǎng)景:
- 當(dāng)Spring Boot默認(rèn)的HttpMessageConverter無(wú)法滿足自定義的序列化和反序列化需求時(shí)。
- 當(dāng)需要處理非標(biāo)準(zhǔn)的媒體類型時(shí),如自定義的二進(jìn)制格式或文本格式。
- 當(dāng)需要在序列化和反序列化過(guò)程中應(yīng)用復(fù)雜的業(yè)務(wù)邏輯時(shí)。
創(chuàng)建一個(gè)自定義的HttpMessageConverter:
public class CustomLocalDateTimeConverter extends MappingJackson2HttpMessageConverter { public CustomLocalDateTimeConverter() { super(); ObjectMapper customObjectMapper = new ObjectMapper(); customObjectMapper.registerModule(new CustomJacksonModule()); setObjectMapper(customObjectMapper); } }
然后,在配置類中注冊(cè)這個(gè)轉(zhuǎn)換器:
@Configuration public class WebConfig implements WebMvcConfigurer { @Override public void extendMessageConverters(List<HttpMessageConverter<?>> converters) { converters.add(0, new CustomLocalDateTimeConverter()); } }
5. 使用AOP進(jìn)行切面編程
可以使用Spring AOP來(lái)對(duì)控制器的方法進(jìn)行切面,從而在方法執(zhí)行前后進(jìn)行自定義的序列化和反序列化操作。
使用場(chǎng)景:
- 當(dāng)需要在不修改原有業(yè)務(wù)代碼的情況下,對(duì)方法入?yún)⒑统鰠⑦M(jìn)行額外的處理時(shí)。
- 當(dāng)需要對(duì)多個(gè)控制器或方法中的入?yún)⒑统鰠?yīng)用統(tǒng)一的處理邏輯時(shí)。
- 當(dāng)處理邏輯與業(yè)務(wù)邏輯相對(duì)獨(dú)立,且需要保持代碼結(jié)構(gòu)清晰時(shí)。
首先,定義一個(gè)切面:
@Aspect @Component public class CustomSerializationAspect { @Before("execution(* com.example.controller..*.*(..)) && args(..,@RequestParam(..),@RequestBody(..))") public void beforeControllerMethod(JoinPoint joinPoint) { // 在這里可以修改入?yún)?,但通常不建議這么做,因?yàn)檫@會(huì)改變方法的簽名 // 更常見(jiàn)的是在處理響應(yīng)后進(jìn)行修改 } @AfterReturning(pointcut = "execution(* com.example.controller..*.*(..)) && @annotation(org.springframework.web.bind.annotation.RequestMapping)", returning = "result") public void afterControllerMethod(JoinPoint joinPoint, Object result) { // 在這里可以修改出參,例如將LocalDateTime轉(zhuǎn)換為特定格式的字符串 if (result instanceof MyEntity) { MyEntity entity = (MyEntity) result; // 假設(shè)你想在這里修改entity的dateTime字段 } } }
注意:AOP通常用于橫切關(guān)注點(diǎn)的處理,如日志、事務(wù)管理等,而不是用于修改方法的入?yún)⒑统鰠ⅰH绻阈枰薷娜雲(yún)⒑统鰠?,通常建議使用其他方法,如自定義的HttpMessageConverter或@ControllerAdvice。在上面的AOP示例中看到了如何捕獲方法的執(zhí)行,但實(shí)際上修改入?yún)⑹遣煌扑]的,而出參的修改也通常不是AOP的最佳用途。如果確實(shí)需要在AOP中修改出參,你可能需要考慮使用@AfterReturning注解,并檢查返回值的類型,然后進(jìn)行相應(yīng)的處理。然而,更常見(jiàn)做法是使用Jackson的序列化特性或@ControllerAdvice來(lái)全局處理響應(yīng)體的格式。
結(jié)語(yǔ)
Spring Boot, Spring Cloud 中要增強(qiáng)請(qǐng)求出入?yún)⒌姆绞街? 通常,對(duì)于簡(jiǎn)單的自定義需求,使用@JsonSerialize和@JsonDeserialize注解是最直接和簡(jiǎn)單的方式。而對(duì)于更復(fù)雜的全局配置或跨多個(gè)控制器的需求,則可能需要使用ObjectMapper的配置或@ControllerAdvice。
以上就是SpringBoot接口請(qǐng)求入?yún)⒑统鰠⒃鰪?qiáng)的五種方法的詳細(xì)內(nèi)容,更多關(guān)于SpringBoot接口出入?yún)⒃鰪?qiáng)的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
分析那些不講武德的SDK(構(gòu)造使用規(guī)范)
這篇文章主要為大家介紹了盤點(diǎn)分析那些不講武德的SDK(構(gòu)造規(guī)范)詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2023-05-05Spring如何實(shí)現(xiàn)輸出帶動(dòng)態(tài)標(biāo)簽的日志
文章介紹了如何通過(guò)動(dòng)態(tài)標(biāo)簽日志實(shí)現(xiàn),解決了部分業(yè)務(wù)代碼在多個(gè)模塊中調(diào)用時(shí)日志無(wú)法直觀看出來(lái)源的問(wèn)題,主要通過(guò)ThreadLocal存儲(chǔ)業(yè)務(wù)標(biāo)簽,并在日志輸出時(shí)插入該標(biāo)簽,實(shí)現(xiàn)日志的動(dòng)態(tài)標(biāo)簽功能,感興趣的朋友一起看看吧2024-12-12Java中的while無(wú)限循環(huán)結(jié)構(gòu)及實(shí)例
這篇文章主要介紹了Java中的while無(wú)限循環(huán)結(jié)構(gòu)及實(shí)例,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2024-01-01JavaSE API實(shí)現(xiàn)生成隨機(jī)數(shù)的2種方法(Random類和Math類的Random方法)
本文主要介紹了JavaSE API實(shí)現(xiàn)生成隨機(jī)數(shù)的2種方法,主要包括Random類和Math類的random方法都可以用來(lái)生成隨機(jī)數(shù),具有一定的參考價(jià)值,感興趣的可以了解一下2023-10-10mybatis中string和date的轉(zhuǎn)換方式
這篇文章主要介紹了mybatis中string和date的轉(zhuǎn)換方式,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2021-08-08Java8新特性之深入解析日期和時(shí)間_動(dòng)力節(jié)點(diǎn)Java學(xué)院整理
這篇文章主要介紹了Java8新特性之深入解析日期和時(shí)間_動(dòng)力節(jié)點(diǎn)Java學(xué)院整理,需要的朋友可以參考下2017-06-06