SpringMVC自定義消息轉(zhuǎn)換器的使用其實(shí)很簡(jiǎn)單
在我們的日常開發(fā)中,作為服務(wù)端,接收的數(shù)據(jù)是加密的字符串。我們可能會(huì)在Controller中獲取到加密的字符串,然后手動(dòng)解密,類似于如下做法(用base64做樣例):
@PostMapping
public void base64Post(String base64Param) throws UnsupportedEncodingException {
String jsonStr = new String(Base64.getDecoder().decode(base64Param), "UTF-8");
}其實(shí)通過SpringMVC的消息轉(zhuǎn)換器HttpMessageConverter可以統(tǒng)一的處理這種問題。
下面就來介紹下實(shí)現(xiàn)方式吧。
什么是消息轉(zhuǎn)換器
在SpringMVC中,可以使用@RequestBody和@ResponseBody兩個(gè)注解,分別完成請(qǐng)求報(bào)文到對(duì)象和對(duì)象到響應(yīng)報(bào)文的轉(zhuǎn)換,這種靈活的消息轉(zhuǎn)換機(jī)制就是利用HttpMessageConverter來實(shí)現(xiàn)的,Spring內(nèi)置了很多HttpMessageConverter,比如MappingJackson2HttpMessageConverter,StringHttpMessageConverter等,下面我們來自定義自己的消息轉(zhuǎn)換器來滿足上面的需求
自定義消息轉(zhuǎn)換器
import com.fasterxml.jackson.databind.ObjectMapper;
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.util.StreamUtils;
import java.io.IOException;
import java.nio.charset.Charset;
import java.util.Base64;
/**
* 針對(duì)Object的base64消息處理器
*/
public class Base64ObjMessageConverter extends AbstractHttpMessageConverter<Object> {
public Base64ObjMessageConverter() {
// 新建一個(gè)我們自定義的媒體類型application/base64obj
super(new MediaType("application", "base64obj", Charset.forName("UTF-8")));
}
@Override
protected boolean supports(Class<?> clazz) {
return true;
}
@Override
protected Object readInternal(Class<? extends Object> clazz, HttpInputMessage inputMessage) throws IOException, HttpMessageNotReadableException {
String source = new String(Base64.getDecoder().decode(StreamUtils.copyToString(inputMessage.getBody(), Charset.forName("UTF-8"))), "UTF-8");
return new ObjectMapper().readValue(source, clazz);
}
@Override
protected void writeInternal(Object obj, HttpOutputMessage outputMessage) throws IOException, HttpMessageNotWritableException {
byte[] encode = Base64.getEncoder().encode(new ObjectMapper().writeValueAsString(obj).getBytes());
outputMessage.getBody().write(encode);
}
}如上,我們繼承了泛型類AbstractHttpMessageConverter,并重寫了它的幾個(gè)方法。
supports:設(shè)置處理哪些類。readInternal:處理輸入內(nèi)容,即處理請(qǐng)求值。writeInternal:處理輸出內(nèi)容,即處理返回值。
構(gòu)造方法定義了要處理的MediaType,這里我定義的是application/base64obj;charset=utf-8,接下來在Controller中也要用到這個(gè)MediaType
上面我自定義的消息轉(zhuǎn)換器處理的是Object類型,你也可以指定泛型為特定的類型,只處理該種類型的數(shù)據(jù)。
將自定義的消息轉(zhuǎn)換器加入到springmvc容器中
這里采用配置類的形式
import org.springframework.context.annotation.Bean;
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 MessageConverterConfig implements WebMvcConfigurer {
@Override
public void extendMessageConverters(List<HttpMessageConverter<?>> converters) {
converters.add(base64ObjMessageConverter());
}
@Bean
public Base64ObjMessageConverter base64ObjMessageConverter() {
return new Base64ObjMessageConverter();
}
}Controller代碼
@PostMapping(value = "base64obj", consumes = "application/base64obj;charset=utf-8",produces = "application/base64obj;charset=utf-8")
public User base64obj(@RequestBody User user) {
System.out.println(user);
return user;
}我們可以通過設(shè)置consumes和produces來讓springmvc采用不同的消息轉(zhuǎn)換器處理我們的請(qǐng)求。
我們的測(cè)試代碼設(shè)置的@PostMapping的屬性consumers和produces都為我們的自定義的消息處理器要處理的類型application/base64obj;charset=utf-8。
即請(qǐng)求和返回都需要經(jīng)過自定義消息處理器Base64ObjMessageConverter的處理。
注意:
- 我們可以將consumers和produces設(shè)置為不同的MediaType來讓不同的消息轉(zhuǎn)換器來處理,但是開發(fā)中一般不會(huì)這么做。
- 比如輸入的格式是XML,返回的格式確實(shí)JSON,這樣做是很逆天的。
- consumers和produces一般都會(huì)采用相同的MediaType。
PostMan請(qǐng)求測(cè)試
我們將json字符串 {"id":1,"name":"name","sex":"男"} 轉(zhuǎn)為base64字符串:eyJpZCI6MSwibmFtZSI6Im5hbWUiLCJzZXgiOiLnlLcifQ==
用postma請(qǐng)求,設(shè)置Content-Type為我們自定義的application/base64obj;charset=utf-8

設(shè)置請(qǐng)求體,發(fā)送請(qǐng)求,結(jié)果能響應(yīng)

總結(jié)
以上為個(gè)人經(jīng)驗(yàn),希望能給大家一個(gè)參考,也希望大家多多支持腳本之家。
相關(guān)文章
Java的DelayQueue延遲隊(duì)列簡(jiǎn)單使用代碼實(shí)例
這篇文章主要介紹了Java的DelayQueue延遲隊(duì)列簡(jiǎn)單使用代碼實(shí)例,DelayQueue是一個(gè)延遲隊(duì)列,插入隊(duì)列的數(shù)據(jù)只有達(dá)到設(shè)置的延遲時(shí)間時(shí)才能被取出,否則線程會(huì)被阻塞,插入隊(duì)列的對(duì)象必須實(shí)現(xiàn)Delayed接口,需要的朋友可以參考下2023-12-12
Java實(shí)現(xiàn)從Html文本中提取純文本的方法
今天小編就為大家分享一篇Java實(shí)現(xiàn)從Html文本中提取純文本的方法,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過來看看吧2018-05-05

