1. 程式人生 > 實用技巧 >ResponseBodyAdvice如何處理返回值是字串的問題

ResponseBodyAdvice如何處理返回值是字串的問題

專案中使用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); @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);
}
}