掃二維碼與項(xiàng)目經(jīng)理溝通
我們?cè)谖⑿派?4小時(shí)期待你的聲音
解答本文疑問(wèn)/技術(shù)咨詢/運(yùn)營(yíng)咨詢/技術(shù)建議/互聯(lián)網(wǎng)交流
環(huán)境:SpringBoot2.7.12

樂(lè)東黎族網(wǎng)站制作公司哪家好,找創(chuàng)新互聯(lián)建站!從網(wǎng)頁(yè)設(shè)計(jì)、網(wǎng)站建設(shè)、微信開(kāi)發(fā)、APP開(kāi)發(fā)、成都響應(yīng)式網(wǎng)站建設(shè)等網(wǎng)站項(xiàng)目制作,到程序開(kāi)發(fā),運(yùn)營(yíng)維護(hù)。創(chuàng)新互聯(lián)建站于2013年創(chuàng)立到現(xiàn)在10年的時(shí)間,我們擁有了豐富的建站經(jīng)驗(yàn)和運(yùn)維經(jīng)驗(yàn),來(lái)保證我們的工作的順利進(jìn)行。專注于網(wǎng)站建設(shè)就選創(chuàng)新互聯(lián)建站。
在Spring MVC中,HttpMessageConverter主要用于將HTTP請(qǐng)求的輸入內(nèi)容轉(zhuǎn)換為指定的Java對(duì)象,以及將Java對(duì)象轉(zhuǎn)換為HTTP響應(yīng)的輸出內(nèi)容。這種靈活的消息轉(zhuǎn)換機(jī)制就是利用HttpMessageConverter來(lái)實(shí)現(xiàn)的。
Spring MVC提供了多個(gè)默認(rèn)的HttpMessageConverter實(shí)現(xiàn),包括處理JSON、XML、文本等格式的Converter。另外,我們也可以自定義HttpMessageConverter來(lái)處理其他格式的數(shù)據(jù)。
Spring MVC提供了兩個(gè)注解:@RequestBody和@ResponseBody,分別用于完成請(qǐng)求報(bào)文到對(duì)象和對(duì)象到響應(yīng)報(bào)文的轉(zhuǎn)換。
然而,有時(shí)候默認(rèn)的HttpMessageConverter無(wú)法滿足特定的需求,例如,當(dāng)我們需要處理的數(shù)據(jù)格式?jīng)]有默認(rèn)的Converter時(shí),或者我們需要對(duì)現(xiàn)有的Converter進(jìn)行擴(kuò)展時(shí),就需要自定義HttpMessageConverter。
自定義HttpMessageConverter可以讓我們更加靈活地控制數(shù)據(jù)轉(zhuǎn)換的過(guò)程,例如我們可以自定義轉(zhuǎn)換規(guī)則、異常處理等。
接下來(lái)我們通過(guò)一個(gè)實(shí)例講解如何自定義HttpMessageConverter。
接口請(qǐng)求數(shù)據(jù)格式:
xxx|yyy|zzz|...
接口返回JSON數(shù)據(jù)格式
{
"xxx": xxx,
"yyy": yyy,
"zzz": zzz,
...
}
其實(shí)就上面的數(shù)據(jù)格式,我們完全可以不用自定義HttpMessageConverter也是完全可以實(shí)現(xiàn)的。我們這里主要就是教大家如何在特殊的需求下實(shí)現(xiàn)特定的數(shù)據(jù)轉(zhuǎn)換處理。
public class PackHttpMessageConverter implements HttpMessageConverter
@Configuration
public class WebMvcConfig implements WebMvcConfigurer {
@Override
public void configureMessageConverters(List> converters) {
converters.add(new PackHttpMessageConverter()) ;
}
}
到這里自定義HttpMessageConverter及注冊(cè)到容器中就全部完成了,開(kāi)發(fā)還是比較簡(jiǎn)單,接下來(lái)做測(cè)試
// 方法非常簡(jiǎn)單還是用的那些常用的類,@RequestBody接收請(qǐng)求body中的內(nèi)容
@PostMapping("/i")
public Object i(@RequestBody Users user) {
System.out.println(handlerAdapter) ;
return user ;
}
通過(guò)Postman測(cè)試接口
設(shè)置請(qǐng)求的header
圖片
圖片
似乎沒(méi)有任何的問(wèn)題,其實(shí)你只要在寫的方法中打印下日志,或者調(diào)試下,你會(huì)發(fā)現(xiàn)你的write方法根本就沒(méi)有被調(diào)用,也就是說(shuō)寫數(shù)據(jù)并沒(méi)有使用到我們自定義的實(shí)現(xiàn),這是因?yàn)橛袃?yōu)先級(jí)比我們自定義的轉(zhuǎn)換器高,所以要想讓寫消息也調(diào)用自定義的。我們需要如下修改注冊(cè)方式:
public void configureMessageConverters(List> converters) {
converters.add(0, new PackHttpMessageConverter()) ;
}
這樣我們自定義的轉(zhuǎn)換器就排到了第一的位置,這樣就會(huì)調(diào)用我們自定義的write方法。
以上就是自定義HttpMessageConverter全部?jī)?nèi)容。
請(qǐng)求參數(shù)由于添加了@RequestBody,所以方法的參數(shù)解析器使用的是RequestResponseBodyMethodProcessor。
public class RequestResponseBodyMethodProcessor extends AbstractMessageConverterMethodProcessor {
protected Object readWithMessageConverters(NativeWebRequest webRequest, MethodParameter parameter,
Type paramType) throws IOException, HttpMediaTypeNotSupportedException, HttpMessageNotReadableException {
// ...
// 讀取請(qǐng)求數(shù)據(jù);調(diào)用父類方法
Object arg = readWithMessageConverters(inputMessage, parameter, paramType);
// ...
}
}
AbstractMessageConverterMethodArgumentResolver
public abstract class AbstractMessageConverterMethodArgumentResolver {
protected Object readWithMessageConverters(...) {
// ...
// 遍歷所有的消息轉(zhuǎn)換器
for (HttpMessageConverter> converter : this.messageConverters) {
Class> converterType = (Class>) converter.getClass();
GenericHttpMessageConverter> genericConverter = (converter instanceof GenericHttpMessageConverter ? (GenericHttpMessageConverter>) converter : null);
// 判斷當(dāng)前轉(zhuǎn)換器是否讀,也就上面我們自定義中實(shí)現(xiàn)的canRead方法
if (genericConverter != null ? genericConverter.canRead(targetType, contextClass, contentType) :
(targetClass != null && converter.canRead(targetClass, contentType))) {
if (message.hasBody()) {
HttpInputMessage msgToUse = getAdvice().beforeBodyRead(message, parameter, targetType, converterType);
// 讀取具體的數(shù)據(jù)內(nèi)容
body = (genericConverter != null ? genericConverter.read(targetType, contextClass, msgToUse) : ((HttpMessageConverter) converter).read(targetClass, msgToUse));
body = getAdvice().afterBodyRead(body, msgToUse, parameter, targetType, converterType);
}
else {
body = getAdvice().handleEmptyBody(null, message, parameter, targetType, converterType);
}
break;
}
}
}
}
原理也比較的簡(jiǎn)單。
自定義HttpMessageConverter是Spring MVC中一個(gè)強(qiáng)大的工具,它可以幫助開(kāi)發(fā)者更加靈活地控制數(shù)據(jù)轉(zhuǎn)換的過(guò)程,滿足特定的需求。

我們?cè)谖⑿派?4小時(shí)期待你的聲音
解答本文疑問(wèn)/技術(shù)咨詢/運(yùn)營(yíng)咨詢/技術(shù)建議/互聯(lián)網(wǎng)交流