Spring中ResponseBodyAdvice的使用詳解
ResponseBodyAdvice可以在注解@ResponseBody將返回值處理成相應(yīng)格式之前操作返回值。實(shí)現(xiàn)這個(gè)接口即可完成相應(yīng)操作。可用于對(duì)response 數(shù)據(jù)的一些統(tǒng)一封裝或者加密等操作
1 ResponseBodyAdvice的簡(jiǎn)介
ResponseBodyAdvice接口和之前記錄的RequestBodyAdvice接口類似, RequestBodyAdvice是請(qǐng)求到Controller之前攔截,做相應(yīng)的處理操作, 而ResponseBodyAdvice是對(duì)Controller返回的{@code @ResponseBody}or a {@code ResponseEntity} 后,{@code HttpMessageConverter} 類型轉(zhuǎn)換之前攔截, 進(jìn)行相應(yīng)的處理操作后,再將結(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要進(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)攔截類
@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接口之類的請(qǐng)求, 不應(yīng)該再次包裝,應(yīng)該直接返回
// 上述問題的解決方案: 可以在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è)返回包裝類
@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ù)庫(kù)中查詢, 案例中也可以使用偽數(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è)試
瀏覽器訪問: http://localhost:8080/hello/one
User(id=1, username=李子柒, phone=77777, icon=李子柒的頭像, queryTime=Wed Oct 27 20:47:02 CST 2021) 響應(yīng)攔截成功
瀏覽器訪問: 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)類型轉(zhuǎn)換異常.
到此這篇關(guān)于Spring中ResponseBodyAdvice的使用的文章就介紹到這了,更多相關(guān)Spring中ResponseBodyAdvice使用內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
Java 改造ayui表格組件實(shí)現(xiàn)多重排序
layui 的表格組件目前只支持單列排序,在實(shí)際應(yīng)用中并不能很好的支撐我們的業(yè)務(wù)需求。今天一時(shí)手癢,決定改造一番以支持多重排序。2021-04-04
spring中@RestController和@Controller的區(qū)別小結(jié)
@RestController和@Controller這兩個(gè)注解用于創(chuàng)建Web應(yīng)用程序的控制器類,那么這兩個(gè)注解有哪些區(qū)別,本文就來介紹一下,并用示例代碼說明,感興趣的可以了解一下2023-09-09
springboot使用spring-data-jpa操作MySQL數(shù)據(jù)庫(kù)
這篇文章主要介紹了springboot使用spring-data-jpa操作MySQL數(shù)據(jù)庫(kù),小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧2018-07-07
SpringBoot+SpringCache實(shí)現(xiàn)兩級(jí)緩存(Redis+Caffeine)
這篇文章主要介紹了SpringBoot+SpringCache實(shí)現(xiàn)兩級(jí)緩存(Redis+Caffeine),文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2021-04-04
java實(shí)現(xiàn)圖片的上傳與展示實(shí)例代碼
這篇文章主要給大家介紹了關(guān)于java實(shí)現(xiàn)圖片的上傳與展示的相關(guān)資料,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2018-12-12

