Spring中ResponseBodyAdvice的使用詳解
ResponseBodyAdvice可以在注解@ResponseBody將返回值處理成相應(yīng)格式之前操作返回值。實(shí)現(xiàn)這個(gè)接口即可完成相應(yīng)操作??捎糜趯?duì)response 數(shù)據(jù)的一些統(tǒng)一封裝或者加密等操作
1 ResponseBodyAdvice的簡(jiǎn)介
ResponseBodyAdvice接口和之前記錄的RequestBodyAdvice接口類(lèi)似, RequestBodyAdvice是請(qǐng)求到Controller之前攔截,做相應(yīng)的處理操作, 而ResponseBodyAdvice是對(duì)Controller返回的{@code @ResponseBody}or a {@code ResponseEntity} 后,{@code HttpMessageConverter} 類(lèi)型轉(zhuǎn)換之前攔截, 進(jìn)行相應(yīng)的處理操作后,再將結(jié)果返回給客戶(hù)端.
ResponseBodyAdvice的源代碼:
/** 數(shù)據(jù)的處理順序向下
* Allows customizing the response after the execution of an {@code @ResponseBody}
* or a {@code ResponseEntity} controller method but before the body is written
* with an {@code HttpMessageConverter}.
*
* <p>Implementations may be registered directly with
* {@code RequestMappingHandlerAdapter} and {@code ExceptionHandlerExceptionResolver}
* or more likely annotated with {@code @ControllerAdvice} in which case they
* will be auto-detected by both.
*
* @author Rossen Stoyanchev
* @since 4.1
* @param <T> the body type
*/
public interface ResponseBodyAdvice<T> {
/**
* Whether this component supports the given controller method return type
* and the selected {@code HttpMessageConverter} type.
* @param returnType the return type 方法返回的類(lèi)型
* @param converterType the selected converter type 參數(shù)類(lèi)型裝換
* @return {@code true} if {@link #beforeBodyWrite} should be invoked;
* {@code false} otherwise
* 返回 true 則下面 beforeBodyWrite方法被調(diào)用, 否則就不調(diào)用下述方法
*/
boolean supports(MethodParameter returnType, Class<? extends HttpMessageConverter<?>> converterType);
/**
* Invoked after an {@code HttpMessageConverter} is selected and just before
* its write method is invoked.
* @param body the body to be written
* @param returnType the return type of the controller method
* @param selectedContentType the content type selected through content negotiation
* @param selectedConverterType the converter type selected to write to the response
* @param request the current request
* @param response the current response
* @return the body that was passed in or a modified (possibly new) instance
*/
@Nullable
T beforeBodyWrite(@Nullable T body, MethodParameter returnType, MediaType selectedContentType,
Class<? extends HttpMessageConverter<?>> selectedConverterType,
ServerHttpRequest request, ServerHttpResponse response);
}
說(shuō)明:
- supports方法: 判斷是否要執(zhí)行beforeBodyWrite方法,true為執(zhí)行,false不執(zhí)行. 通過(guò)該方法可以選擇哪些類(lèi)或那些方法的response要進(jìn)行處理, 其他的不進(jìn)行處理.
- beforeBodyWrite方法: 對(duì)response方法進(jìn)行具體操作處理
{@code @ResponseBody} 返回響應(yīng)體, 例如List集合
{@code ResponseEntity} 返回響應(yīng)實(shí)體對(duì)象,例如User對(duì)象
2 ResponseBodyAdvice的使用
1 準(zhǔn)備一個(gè)SpringBoot項(xiàng)目環(huán)境
2 添加一個(gè)響應(yīng)攔截類(lèi)
@ControllerAdvice
public class BaseResponseBodyAdvice implements ResponseBodyAdvice<Object> {
@Override
public boolean supports(MethodParameter returnType, Class converterType) {
return true;
}
@Override
public Object beforeBodyWrite(Object body, MethodParameter returnType,
MediaType selectedContentType, Class selectedConverterType, ServerHttpRequest request,
ServerHttpResponse response) {
// 遇到feign接口之類(lèi)的請(qǐng)求, 不應(yīng)該再次包裝,應(yīng)該直接返回
// 上述問(wèn)題的解決方案: 可以在feign攔截器中,給feign請(qǐng)求頭中添加一個(gè)標(biāo)識(shí)字段, 表示是feign請(qǐng)求
// 在此處攔截到feign標(biāo)識(shí)字段, 則直接放行 返回body.
System.out.println("響應(yīng)攔截成功");
if (body instanceof BaseResponse) {
return body;
} else if (body == null) {
return BaseResponse.ok();
} else {
return BaseResponse.ok(body);
}
}
}
3 添加一個(gè)返回包裝類(lèi)
@Data
@AllArgsConstructor
@NoArgsConstructor
public class BaseResponse<T> {
private T data;
private int status = 200;
private String message;
private long srvTime = System.currentTimeMillis();
public BaseResponse(String message) {
this.message = message;
}
public BaseResponse<T> setData(T data) {
this.data = data;
return this;
}
public static <T> BaseResponse<T> ok() {
return new BaseResponse<>("操作成功");
}
public static <T> BaseResponse<T> ok(T data) {
return new BaseResponse<T>("操作成功").setData(data);
}
}
4 添加控制類(lèi)
@Controller
@RequestMapping("/hello")
public class HelloWorld {
// 此處數(shù)據(jù)從數(shù)據(jù)庫(kù)中查詢(xún), 案例中也可以使用偽數(shù)據(jù)代替
@Autowired
private UserMapper userMapper;
// {@code ResponseEntity} 案列
@GetMapping("/one")
@ResponseBody
public User one() {
List<User> users = userMapper.selectAll();
System.out.println(users.get(0));
return users.get(0);
}
// {@code @ResponseBody} 案列
@GetMapping("/list")
@ResponseBody
public List<User> list() {
List<User> users = userMapper.selectAll();
System.out.println(users);
return users;
}
}
5 接口測(cè)試
瀏覽器訪(fǎng)問(wèn): http://localhost:8080/hello/one
User(id=1, username=李子柒, phone=77777, icon=李子柒的頭像, queryTime=Wed Oct 27 20:47:02 CST 2021) 響應(yīng)攔截成功
瀏覽器訪(fǎng)問(wèn): http://localhost:8080/hello/list
[User(id=1, username=李子柒, phone=77777, icon=李子柒的頭像, queryTime=Wed Oct 27 20:46:58 CST 2021)] 響應(yīng)攔截成功
ps: 如果直接響應(yīng)字符串返回,則會(huì)報(bào)類(lèi)型轉(zhuǎn)換異常.
到此這篇關(guān)于Spring中ResponseBodyAdvice的使用的文章就介紹到這了,更多相關(guān)Spring中ResponseBodyAdvice使用內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
JAVA 集成 PF4J 插件框架的應(yīng)用場(chǎng)景分析
PF4J是一個(gè)強(qiáng)大的Java插件框架,允許開(kāi)發(fā)者將應(yīng)用程序分解為可擴(kuò)展的模塊,本文介紹了PF4J的基本概念和如何在Java項(xiàng)目中集成,本文給大家介紹的非常詳細(xì),感興趣的朋友一起看看吧2025-03-03
淺談Java由于不當(dāng)?shù)膱?zhí)行順序?qū)е碌乃梨i
為了保證線(xiàn)程的安全,我們引入了加鎖機(jī)制,但是如果不加限制的使用加鎖,就有可能會(huì)導(dǎo)致順序死鎖(Lock-Ordering Deadlock)。本文將會(huì)討論一下順序死鎖的問(wèn)題。2021-06-06
java.sql.SQLException:com.mysql.cj.jdbc.Driver報(bào)錯(cuò)問(wèn)題解決
這篇文章主要給大家介紹了關(guān)于java.sql.SQLException:com.mysql.cj.jdbc.Driver報(bào)錯(cuò)問(wèn)題解決的相關(guān)資料,文中通過(guò)圖文介紹的非常詳細(xì),需要的朋友可以參考下2023-08-08
Java圖書(shū)管理系統(tǒng)課程設(shè)計(jì)
這篇文章主要為大家詳細(xì)介紹了Java圖書(shū)管理系統(tǒng)課程設(shè)計(jì),文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2022-02-02
java實(shí)現(xiàn)圖片轉(zhuǎn)ascii字符畫(huà)的方法示例
這篇文章主要介紹了java實(shí)現(xiàn)圖片轉(zhuǎn)ascii字符畫(huà)的方法示例,小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧2018-08-08
java結(jié)合prometheus如何實(shí)現(xiàn)自定義數(shù)據(jù)監(jiān)控
文章介紹了如何配置Prometheus監(jiān)控系統(tǒng),包括配置文件prometheus.yml、被監(jiān)控應(yīng)用的指標(biāo)暴露配置以及自定義監(jiān)控指標(biāo)的實(shí)現(xiàn),同時(shí),還詳細(xì)說(shuō)明了監(jiān)控應(yīng)用如何通過(guò)Prometheus API獲取數(shù)據(jù)、處理數(shù)據(jù)并返回結(jié)果2024-12-12
java 實(shí)現(xiàn)音樂(lè)播放器的簡(jiǎn)單實(shí)例
這篇文章主要介紹了java 實(shí)現(xiàn)音樂(lè)播放器的簡(jiǎn)單實(shí)例的相關(guān)資料,希望通過(guò)本文能幫助到大家,實(shí)現(xiàn)這樣的功能,需要的朋友可以參考下2017-09-09
Java數(shù)據(jù)導(dǎo)入功能之讀取Excel文件實(shí)例
這篇文章主要介紹了Java數(shù)據(jù)導(dǎo)入功能之讀取Excel文件實(shí)例,本文給出了jar包的下載地址以及讀取Excel文件的代碼實(shí)例,需要的朋友可以參考下2015-06-06

