• 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);
        }
    }
  • 相关阅读:
    2016/3/28 大三下第一月
    hihoCoder1284机会渺茫(唯一分解定理 + 约分)
    瞬沐队小组会议
    本周编程
    团队简介及团队课题
    本周编程
    Python环境的配置
    疫情图表
    本周编程
    返回一个数组中和最大的子数组
  • 原文地址:https://www.cnblogs.com/caozx/p/13329468.html
Copyright © 2020-2023  润新知