聊聊springboot中如何自定義消息轉(zhuǎn)換器
Spring Boot 中的消息轉(zhuǎn)換器(HttpMessageConverter)是處理 HTTP 請(qǐng)求和響應(yīng)數(shù)據(jù)格式轉(zhuǎn)換的核心組件,負(fù)責(zé)將 HTTP 請(qǐng)求體中的數(shù)據(jù)轉(zhuǎn)換為 Java 對(duì)象,或?qū)?Java 對(duì)象轉(zhuǎn)換為 HTTP 響應(yīng)體的數(shù)據(jù)。
核心接口
public interface HttpMessageConverter<T> {
boolean canRead(Class<?> clazz, @Nullable MediaType mediaType);
boolean canWrite(Class<?> clazz, @Nullable MediaType mediaType);
List<MediaType> getSupportedMediaTypes();
default List<MediaType> getSupportedMediaTypes(Class<?> clazz) {
return !this.canRead(clazz, (MediaType)null) && !this.canWrite(clazz, (MediaType)null) ? Collections.emptyList() : this.getSupportedMediaTypes();
}
T read(Class<? extends T> clazz, HttpInputMessage inputMessage) throws IOException, HttpMessageNotReadableException;
void write(T t, @Nullable MediaType contentType, HttpOutputMessage outputMessage) throws IOException, HttpMessageNotWritableException;
}getSupportedMediaTypes 定義支持的媒體類(lèi)型(如:application/json)
canRead/canWrite:判斷是否支持讀寫(xiě)操作
read/write:執(zhí)行具體的數(shù)據(jù)轉(zhuǎn)換邏輯
springboot默認(rèn)提供的轉(zhuǎn)換器
Spring Boot 自動(dòng)配置了以下常用消息轉(zhuǎn)換器:
- StringHttpMessageConverter - 處理文本數(shù)據(jù)
- MappingJackson2HttpMessageConverter - 處理 JSON 數(shù)據(jù)(使用 Jackson)
- FormHttpMessageConverter - 處理表單數(shù)據(jù)
- ByteArrayHttpMessageConverter - 處理字節(jié)數(shù)組
- ResourceHttpMessageConverter - 處理資源文件
- Jaxb2RootElementHttpMessageConverter - 處理 XML(使用 JAXB)
- AllEncompassingFormHttpMessageConverter - 增強(qiáng)的表單處理器
springboot在啟動(dòng)的時(shí)候就會(huì)自動(dòng)注冊(cè)上述默認(rèn)的轉(zhuǎn)換器,有請(qǐng)求進(jìn)來(lái)的時(shí)候會(huì)根據(jù)請(qǐng)求的accept和響應(yīng)的Content-Type,選擇匹配的轉(zhuǎn)換器,若多個(gè)轉(zhuǎn)換器都支持,則按注冊(cè)順序優(yōu)先。
如何自定義消息轉(zhuǎn)換器
比如自定義個(gè)fastjson轉(zhuǎn)換器
import com.alibaba.fastjson2.JSON;
import com.alibaba.fastjson2.support.config.FastJsonConfig;
import org.springframework.http.HttpInputMessage;
import org.springframework.http.HttpOutputMessage;
import org.springframework.http.MediaType;
import org.springframework.http.converter.AbstractHttpMessageConverter;
import org.springframework.http.converter.HttpMessageNotReadableException;
import org.springframework.http.converter.HttpMessageNotWritableException;
import org.springframework.lang.NonNull;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.lang.reflect.Type;
import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.List;
public class FastJsonHttpMessageConverter extends AbstractHttpMessageConverter<Object> {
private final FastJsonConfig fastJsonConfig = new FastJsonConfig();
public FastJsonHttpMessageConverter() {
// 支持多種媒體類(lèi)型
List<MediaType> supportedMediaTypes = new ArrayList<>();
supportedMediaTypes.add(MediaType.APPLICATION_JSON);
supportedMediaTypes.add(new MediaType("application", "*+json"));
setSupportedMediaTypes(supportedMediaTypes);
// 配置FastJson
fastJsonConfig.setDateFormat("yyyy-MM-dd HH:mm:ss");
fastJsonConfig.setCharset(StandardCharsets.UTF_8);
}
@Override
protected boolean supports(@NonNull Class<?> clazz) {
return true; // 支持所有類(lèi)型
}
@Override
protected Object readInternal(
@NonNull Class<?> clazz,
@NonNull HttpInputMessage inputMessage
) throws IOException, HttpMessageNotReadableException {
try (InputStream in = inputMessage.getBody()) {
return JSON.parseObject(
in,
fastJsonConfig.getCharset(),
clazz,
fastJsonConfig.getFeatures()
);
} catch (Exception e) {
throw new HttpMessageNotReadableException(
"JSON parse error: " + e.getMessage(),
inputMessage
);
}
}
@Override
protected void writeInternal(
@NonNull Object object,
@NonNull HttpOutputMessage outputMessage
) throws IOException, HttpMessageNotWritableException {
try (OutputStream out = outputMessage.getBody()) {
JSON.writeTo(
out,
object,
fastJsonConfig.getCharset(),
fastJsonConfig.getFeatures(),
fastJsonConfig.getFilters(),
fastJsonConfig.getDateFormat(),
JSON.DEFAULT_GENERATE_FEATURE,
fastJsonConfig.getWriterFeatures()
);
} catch (Exception e) {
throw new HttpMessageNotWritableException(
"JSON write error: " + e.getMessage(),
e
);
}
}
public FastJsonConfig getFastJsonConfig() {
return fastJsonConfig;
}
public void setFastJsonConfig(FastJsonConfig fastJsonConfig) {
this.fastJsonConfig.setDateFormat(fastJsonConfig.getDateFormat());
this.fastJsonConfig.setCharset(fastJsonConfig.getCharset());
this.fastJsonConfig.setFeatures(fastJsonConfig.getFeatures());
this.fastJsonConfig.setReaderFeatures(fastJsonConfig.getReaderFeatures());
this.fastJsonConfig.setWriterFeatures(fastJsonConfig.getWriterFeatures());
this.fastJsonConfig.setFilters(fastJsonConfig.getFilters());
}
}注冊(cè)自定義的消息轉(zhuǎn)換器
import org.springframework.context.annotation.Configuration;
import org.springframework.http.converter.HttpMessageConverter;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
import java.util.List;
@Configuration
public class FastJsonWebConfig implements WebMvcConfigurer {
@Override
public void configureMessageConverters(List<HttpMessageConverter<?>> converters) {
// 創(chuàng)建FastJson消息轉(zhuǎn)換器
FastJsonHttpMessageConverter fastJsonConverter = new FastJsonHttpMessageConverter();
// 可以在這里進(jìn)一步配置FastJson
// fastJsonConverter.getFastJsonConfig().setDateFormat("yyyy-MM-dd");
// 將FastJson轉(zhuǎn)換器添加到轉(zhuǎn)換器列表的最前面
converters.add(0, fastJsonConverter);
}
}注意這里優(yōu)先級(jí)的問(wèn)題,要把fastjson的放前面,這樣才會(huì)優(yōu)先走咱自定義的fastjson的轉(zhuǎn)換器,而不是默認(rèn)的gson的
到此這篇關(guān)于聊聊springboot中如何自定義消息轉(zhuǎn)換器的文章就介紹到這了,更多相關(guān)springboot 消息轉(zhuǎn)換器內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
idea?compile項(xiàng)目正常啟動(dòng)項(xiàng)目的時(shí)候build失敗報(bào)“找不到符號(hào)”等問(wèn)題及解決方案
這篇文章主要介紹了idea?compile項(xiàng)目正常,啟動(dòng)項(xiàng)目的時(shí)候build失敗,報(bào)“找不到符號(hào)”等問(wèn)題,這種問(wèn)題屬于lombok編譯失敗導(dǎo)致,可能原因是依賴(lài)jar包沒(méi)有更新到最新版本,需要的朋友可以參考下2023-10-10
Spring @Valid和@Validated區(qū)別和用法實(shí)例
這篇文章主要介紹了Spring @Valid和@Validated區(qū)別和用法實(shí)例,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下2020-04-04
java中如何實(shí)現(xiàn)對(duì)類(lèi)的對(duì)象進(jìn)行排序
在本篇文章里小編給各位整理一篇關(guān)于java中如何實(shí)現(xiàn)對(duì)類(lèi)的對(duì)象進(jìn)行排序知識(shí)點(diǎn)內(nèi)容,有興趣的朋友們可以學(xué)習(xí)下。2020-02-02
SpringBoot和前端Vue的跨域問(wèn)題及解決方案
所謂跨域就是從 A 向 B 發(fā)請(qǐng)求,如若他們的地址協(xié)議、域名、端口都不相同,直接訪問(wèn)就會(huì)造成跨域問(wèn)題,跨域是非常常見(jiàn)的現(xiàn)象,這篇文章主要介紹了解決SpringBoot和前端Vue的跨域問(wèn)題,需要的朋友可以參考下2023-11-11
在Java中實(shí)現(xiàn)線程之間的數(shù)據(jù)共享的幾種方式總結(jié)
在 Java 中實(shí)現(xiàn)線程間數(shù)據(jù)共享是并發(fā)編程的核心需求,但需要謹(jǐn)慎處理同步問(wèn)題以避免競(jìng)態(tài)條件,本文通過(guò)代碼示例給大家介紹了幾種主要實(shí)現(xiàn)方式及其最佳實(shí)踐,需要的朋友可以參考下2025-08-08
聊聊注解@controller@service@component@repository的區(qū)別
這篇文章主要介紹了聊聊注解@controller@service@component@repository的區(qū)別,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2021-08-08

