項目中使用ResponseBodyAdvice同一封裝返回格式,對於一般的類型都沒有問題,但是處理字符串時,遇到了類型轉換的問題,debug一步一步跟蹤,原來是對於字符串的ContentType是“text-plain”,ConverterType是StringHttpMessageConverter這個類型轉換,由於將結果封裝成了自定義的Result類型,所以有Result轉換成String報錯。
如何改正呢,其實很簡單,將返回String的ContentType變成“application/json; charset=UTF-8“。然后將自定義的Result轉換成json字符串,上代碼:
1:想在前台js里面直接當成json使用,需要將返回String的ContentType變成“application/json; charset=UTF-8“,produces即完成此部分工作。@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字符串,下面對String類型處理為重點
/**
* 根據標識,統一返回類型
*/
@ControllerAdvice
public class ResponseResultHandler implements ResponseBodyAdvice{
private final Logger logger = LoggerFactory.getLogger(ResponseResultHandler.class);
@Override
public 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);
}
}