Spring中ResponseBodyAdvice的使用詳解
ResponseBodyAdvice可以在注解@ResponseBody將返回值處理成相應格式之前操作返回值。實現(xiàn)這個接口即可完成相應操作。可用于對response 數(shù)據(jù)的一些統(tǒng)一封裝或者加密等操作
1 ResponseBodyAdvice的簡介
ResponseBodyAdvice接口和之前記錄的RequestBodyAdvice接口類似, RequestBodyAdvice是請求到Controller之前攔截,做相應的處理操作, 而ResponseBodyAdvice是對Controller返回的{@code @ResponseBody}or a {@code ResponseEntity} 后,{@code HttpMessageConverter} 類型轉(zhuǎn)換之前攔截, 進行相應的處理操作后,再將結(jié)果返回給客戶端.
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 方法返回的類型
* @param converterType the selected converter type 參數(shù)類型裝換
* @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);
}
說明:
- supports方法: 判斷是否要執(zhí)行beforeBodyWrite方法,true為執(zhí)行,false不執(zhí)行. 通過該方法可以選擇哪些類或那些方法的response要進行處理, 其他的不進行處理.
- beforeBodyWrite方法: 對response方法進行具體操作處理
{@code @ResponseBody} 返回響應體, 例如List集合
{@code ResponseEntity} 返回響應實體對象,例如User對象
2 ResponseBodyAdvice的使用
1 準備一個SpringBoot項目環(huán)境
2 添加一個響應攔截類
@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接口之類的請求, 不應該再次包裝,應該直接返回
// 上述問題的解決方案: 可以在feign攔截器中,給feign請求頭中添加一個標識字段, 表示是feign請求
// 在此處攔截到feign標識字段, 則直接放行 返回body.
System.out.println("響應攔截成功");
if (body instanceof BaseResponse) {
return body;
} else if (body == null) {
return BaseResponse.ok();
} else {
return BaseResponse.ok(body);
}
}
}
3 添加一個返回包裝類
@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 添加控制類
@Controller
@RequestMapping("/hello")
public class HelloWorld {
// 此處數(shù)據(jù)從數(shù)據(jù)庫中查詢, 案例中也可以使用偽數(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 接口測試
瀏覽器訪問: http://localhost:8080/hello/one
User(id=1, username=李子柒, phone=77777, icon=李子柒的頭像, queryTime=Wed Oct 27 20:47:02 CST 2021) 響應攔截成功
瀏覽器訪問: http://localhost:8080/hello/list
[User(id=1, username=李子柒, phone=77777, icon=李子柒的頭像, queryTime=Wed Oct 27 20:46:58 CST 2021)] 響應攔截成功
ps: 如果直接響應字符串返回,則會報類型轉(zhuǎn)換異常.
到此這篇關于Spring中ResponseBodyAdvice的使用的文章就介紹到這了,更多相關Spring中ResponseBodyAdvice使用內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!
相關文章
淺談Java由于不當?shù)膱?zhí)行順序?qū)е碌乃梨i
為了保證線程的安全,我們引入了加鎖機制,但是如果不加限制的使用加鎖,就有可能會導致順序死鎖(Lock-Ordering Deadlock)。本文將會討論一下順序死鎖的問題。2021-06-06
java.sql.SQLException:com.mysql.cj.jdbc.Driver報錯問題解決
這篇文章主要給大家介紹了關于java.sql.SQLException:com.mysql.cj.jdbc.Driver報錯問題解決的相關資料,文中通過圖文介紹的非常詳細,需要的朋友可以參考下2023-08-08
java實現(xiàn)圖片轉(zhuǎn)ascii字符畫的方法示例
這篇文章主要介紹了java實現(xiàn)圖片轉(zhuǎn)ascii字符畫的方法示例,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧2018-08-08
java結(jié)合prometheus如何實現(xiàn)自定義數(shù)據(jù)監(jiān)控
文章介紹了如何配置Prometheus監(jiān)控系統(tǒng),包括配置文件prometheus.yml、被監(jiān)控應用的指標暴露配置以及自定義監(jiān)控指標的實現(xiàn),同時,還詳細說明了監(jiān)控應用如何通過Prometheus API獲取數(shù)據(jù)、處理數(shù)據(jù)并返回結(jié)果2024-12-12
Java數(shù)據(jù)導入功能之讀取Excel文件實例
這篇文章主要介紹了Java數(shù)據(jù)導入功能之讀取Excel文件實例,本文給出了jar包的下載地址以及讀取Excel文件的代碼實例,需要的朋友可以參考下2015-06-06

