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


項目中使用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);
    }
}


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM