亚洲精品久久久中文字幕-亚洲精品久久片久久-亚洲精品久久青草-亚洲精品久久婷婷爱久久婷婷-亚洲精品久久午夜香蕉

您的位置:首頁技術(shù)文章
文章詳情頁

Spring Boot統(tǒng)一返回體的踩坑記錄

瀏覽:109日期:2023-03-12 10:25:58
前言

在Spring Boot項目中我們可以通過RestControllerAdvice配合實(shí)現(xiàn)ResponseBodyAdvice<T>接口來保證Spring MVC接口具有統(tǒng)一的返回格式,以保證前端同學(xué)能夠封裝統(tǒng)一的數(shù)據(jù)接收工具。但是很多網(wǎng)上的文章并沒有對實(shí)際開發(fā)中的細(xì)節(jié)作出更多的講解。今天胖哥就來分享一下我的采坑經(jīng)歷,也算作一個總結(jié)。

控制作用范圍

我記得在前面關(guān)于Swagger3的文章中提過,如果我們不指定范圍將導(dǎo)致Swagger無法識別接口的元信息。因此如果你使用了Swagger必須指定其范圍,這里你可以通過指定掃描包來指定其作用域:

@RestControllerAdvice('cn.felord.controller')

如果你的Spring MVC控制器有統(tǒng)一的父類控制器的話,

@RestController@RequestMapping('/foo')public class FooController extends BaseController { //todo 省略}

也可以這樣:

@RestControllerAdvice(assignableTypes = BaseController.class)白名單

有些接口可能根據(jù)業(yè)務(wù)需要或者協(xié)議需要不能使用統(tǒng)一返回體,例如支付的通知應(yīng)答。這就需要一個類似白名單的機(jī)制來繞過統(tǒng)一返回體控制器通知類。我們可以借助于ResponseBodyAdvice<T>的下列方法實(shí)現(xiàn):

boolean supports(MethodParameter returnType, Class<? extends HttpMessageConverter<?>> converterType);

這個方法如果返回false就表示不執(zhí)行統(tǒng)一返回體的封裝邏輯。這里我推薦注解實(shí)現(xiàn)。定義一個標(biāo)記注解,可以定義在類上或者方法上:

@Documented@Inherited@Target({ElementType.ANNOTATION_TYPE, ElementType.METHOD})@Retention(RetentionPolicy.RUNTIME)public @interface IgnoreRestBody {}

然后上面的supports方法這樣實(shí)現(xiàn):

@Overridepublic boolean supports(MethodParameter returnType, Class<? extends HttpMessageConverter<?>> converterType) { return !returnType.hasMethodAnnotation(IgnoreRestBody.class);}

如果某個Controller下所有的方法都繞過,就把這個注解標(biāo)記在控制器類上;如果只想忽略某個方法上就把它標(biāo)記在該方法上即可。

返回獨(dú)立字符串的問題

有些接口我們會返回一個字符串:

@GetMapping('/get')public String getStr(){ //返回了一個字符串 return 'felord.cn';}

我們希望這個字符串被統(tǒng)一返回體處理,類似這樣:

{ code: 200, data: 'felord.cn', msg: '返回成字符串',}

但是你會發(fā)現(xiàn)并沒有達(dá)到期望的效果,會拋出類型轉(zhuǎn)換異常。這是因為當(dāng)我們的Spring MVC接口返回數(shù)據(jù)時,會根據(jù)Content-Type來選擇一個HttpMessageConverter來處理,而字符串在不聲明Content-Type的情況下優(yōu)先使用StringHttpMessageConverter ,就導(dǎo)致了轉(zhuǎn)換異常,需要設(shè)定成MappingJackson2HttpMessageConverter用Jackson來處理,Spring MVC的對應(yīng)配置如下:

@Configuration(proxyBeanMethods = false)public class SpringMvcConfiguration implements WebMvcConfigurer { @Override public void configureMessageConverters(List<HttpMessageConverter<?>> converters) {// 解決 String 統(tǒng)一封裝RestBody的問題converters.add(0, new MappingJackson2HttpMessageConverter()); }}

嗯,這樣就起效了!你以為這樣就完了?你會發(fā)現(xiàn)你的JSON序列化不按照你設(shè)置的策略執(zhí)行了。因為你new了一個而不是采用系統(tǒng)初始化的那個。解決方法為,將Spring IoC中的ObjectMapper注入到MappingJackson2HttpMessageConverter中去。或者你使用Debug調(diào)試出系統(tǒng)默認(rèn)的MappingJackson2HttpMessageConverter的位置,比如我的索引為7,就可以這樣配置:

@Configuration(proxyBeanMethods = false)public class SpringMvcConfiguration implements WebMvcConfigurer { @Override public void configureMessageConverters(List<HttpMessageConverter<?>> converters) {// 解決 String 統(tǒng)一封裝RestBody的問題HttpMessageConverter<?> httpMessageConverter = converters.get(7);if (!(httpMessageConverter instanceof MappingJackson2HttpMessageConverter)) { // 確保正確,如果有改動就重新debug throw new RuntimeException('MappingJackson2HttpMessageConverter is not here');}converters.add(0, httpMessageConverter); }}Data的類型問題

曾經(jīng)一個安卓開發(fā)同學(xué)說,你這統(tǒng)一結(jié)構(gòu)中的data如果是數(shù)組:

{ code: 200, data: [’a’,’b’], msg: '返回成字符串',}

后續(xù)如果data添加其它與數(shù)組沒有關(guān)系的屬性就不兼容了,你應(yīng)該保證這個data是個Map。是的,這也是問題,實(shí)際中發(fā)現(xiàn)不僅僅是數(shù)組,如果是int、long等原始類型或者String類型都面臨這種情況,需要加一個額外的判斷body是不是可能改變data類型的類型:

private boolean checkPrimitive(Object body) { Class<?> clazz = body.getClass(); return clazz.isPrimitive() || clazz.isArray() || Collection.class.isAssignableFrom(clazz) || body instanceof Number || body instanceof Boolean || body instanceof Character || body instanceof String;}

然后我們在ResponseBodyAdvice<T>實(shí)現(xiàn)中增加一個判斷:

// 增強(qiáng)擴(kuò)展性if (checkPrimitive(body)) { return RestBody.okData(Collections.singletonMap('result', body));}

就解決問題了。

總結(jié)

今天對Spring Boot中統(tǒng)一返回體的一些細(xì)節(jié)問題進(jìn)行了分享,希望能夠幫助你解決一些實(shí)際開發(fā)中遇到的同樣問題。

到此這篇關(guān)于Spring Boot統(tǒng)一返回體踩坑記錄的文章就介紹到這了,更多相關(guān)Spring Boot統(tǒng)一返回體內(nèi)容請搜索好吧啦網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持好吧啦網(wǎng)!

標(biāo)簽: Spring
相關(guān)文章:
主站蜘蛛池模板: 看欧美的一级毛片 | 国产一级理仑片日本 | 最新国产成人盗摄精品视频 | 日韩欧美亚洲国产一区二区三区 | 久草在线观看福利视频 | 亚洲精品日本高清中文字幕 | 美女黄色免费在线观看 | 日本免费一区二区在线观看 | 国产剧情一区二区 | 欧洲精品码一区二区三区免费看 | 亚洲国产精品人久久 | 精品视频午夜一区二区 | 正在播真实出轨炮对白 | julia一区福利视频在线观看 | 免费看污的网站 | 亚洲成人国产 | 香蕉依依精品视频在线播放 | 国产成人精品一区二区不卡 | 99久久婷婷国产综合精品hsex | 伊人久久综合影院 | 青青伊人影院 | 亚洲欧美在线精品 | 在线观看亚洲精品专区 | 国产一区 在线播放 | 国产精品视频区 | 在线观看免费视频片 | 亚洲小视频 | 成人区视频 | 国产欧美亚洲精品 | 亚洲欧美一区二区三区四区 | 在线观看日本一区 | 有码中文字幕 | 亚洲1区 | 精品国产成人 | 草草视频网站 | 国产美女在线一区二区三区 | 日韩欧美毛片免费观看视频 | 欧美日韩在线观看一区二区 | 亚洲视频在线一区二区 | 亚洲欧美精品一中文字幕 | 一区二区三区视频网站 |