ResponseBodyAdvice如何處理返回值是字串的問題
阿新 • • 發佈:2020-07-17
專案中使用ResponseBodyAdvice同一封裝返回格式,對於一般的型別都沒有問題,但是處理字串時,遇到了型別轉換的問題,debug一步一步跟蹤,原來是對於字串的ContentType是“text-plain”,ConverterType是StringHttpMessageConverter這個型別轉換,由於將結果封裝成了自定義的Result型別,所以有Result轉換成String報錯。
如何改正呢,其實很簡單,將返回String的ContentType變成“application/json; charset=UTF-8“。然後將自定義的Result轉換成json字串,上程式碼:
1:將返回String的ContentType變成“application/json; charset=UTF-8“,下面程式碼標紅部分即完成此部分工作。@ResponseResult此註解是用來標識哪些類或者方法需要統一返回格式。
@RequestMapping(value = "/do_login",produces = "application/json; charset=UTF-8")
@ResponseBody
@ResponseResult
public String doLogin(HttpServletResponse response, @Valid LoginVo loginVo) {log.info(loginVo.toString());
//登入
String token = userService.login(response, loginVo);
return token;
}
2:將自定義的Result轉換成json字串,下面標紅的部分為重點
/**
* 根據標識,統一返回型別
*/
@ControllerAdvice
public class ResponseResultHandler implements ResponseBodyAdvice{ private final Logger logger = LoggerFactory.getLogger(ResponseResultHandler.class); @Overridepublic boolean supports(MethodParameter returnType, Class converterType) {
ServletRequestAttributes sr = (ServletRequestAttributes)RequestContextHolder.getRequestAttributes();
HttpServletRequest request = sr.getRequest();
//這裡是往request獲取一個引數,這個引數標識是否需要統一返回格式,設定引數的過程就是寫了一個攔截器,判斷有無@ResponseResult註解,如果有存入這個標識引數
ResponseResult ResponseResult = (ResponseResult)request.getAttribute(ResponseResultInterceptor.RESPONSE_RESULT_ANN);
request.removeAttribute(ResponseResultInterceptor.RESPONSE_RESULT_ANN);
return ResponseResult == null ? false:true;
} @Override
public Object beforeBodyWrite(Object body, MethodParameter returnType, MediaType selectedContentType, Class selectedConverterType, ServerHttpRequest request, ServerHttpResponse response) {
logger.info("進入返回體,重寫格式中");
if(body instanceof GlobalException){
logger.info("返回值異常,做包裝異常處理");
GlobalException gx = (GlobalException)body;
return Result.error(gx.getCm());
}
//已經是Result型別不做處理,全域性異常處理就是返回的Result型別
//拋異常時先是全域性異常處理程式處理,然後才是返回結果處理
if(body instanceof Result){
return body;
} //當返回型別是String時,用的是StringHttpMessageConverter轉換器,無法轉換為Json格式
//必須在方法體上標註RequestMapping(produces = "application/json; charset=UTF-8")
if(body instanceof String){
String str = JSON.toJSONString(Result.success(body));
return str;
}
return Result.success(body);
}
}