SPRING REST API 返回结果处理和异常处理

包装正常返回结果

Spring 提供了 ResponseBodyAdvice interface, 处理ResonseEntity 返回值,这个接口实现了两个方法,可以实现返回结果的自定义处理

@ControllerAdvice(annotations = {RestController.class})
public class ApiResponseAdvice implements ResponseBodyAdvice {


    @Override
    public boolean supports(MethodParameter returnType, Class converterType) {
        return true;
    }

    @Override
    public Object beforeBodyWrite(Object body, MethodParameter returnType, MediaType selectedContentType, Class selectedConverterType,
                                  ServerHttpRequest request, ServerHttpResponse response) {

        if (selectedContentType.includes(MediaType.APPLICATION_JSON) ||
                selectedContentType.includes(MediaType.APPLICATION_JSON_UTF8)) {
            if (!response.getHeaders().containsKey(SDKConstant.NOT_TRANSFORM_BODY)) {  //有些错误已经格式化为指定的返回类型
                Map<String, Object> map = new HashMap<>();
                map.put("errorCode", 200);
                map.put("message", "success");
                map.put("data", body);
                return map;
            } else {
                return body;
            }
        }
        return body;
    }
}

  1. @ControllerAdvice 这个Annotation 是指定要处理的Controller, 这个处理所有带 @RestController 的Controller.

  2. supports(...) 方法,可以指定需要处理的方法

  3. beforeBodyWrite(...) 方法,进一步过滤处理最后的结果

Controller 异常处理

@ControllerAdvice(annotations = {RestController.class})
  public class RestResponseEntityExceptionHandler extends ResponseEntityExceptionHandler{
        
                @ExceptionHandler(value = ScBaseException.class)
                public void exceptionHandle(...){
                    // 这里你可以返回新的body
                }
}

  1. @ExceptionHandle 这个新增的注解就是用来处理最后抛到Controller的异常,这个也是自定义可以控制的地方非常多,比如我们自定的异常

  2. 但是这个好像捕获不了参数校验等异常,所以再加上第三步

Validator 异常 和 参数错误等校验异常处理

在RestController 中, Validator 异常 和 参数错误等校验异常处理,会重定向至 /error 的请求,所以我们会在这里做处理

Validator 异常

@RequestMapping(value = "/search/code", method = RequestMethod.GET)
public ResponseEntity<Object> getCompanyCodeSearchResult(@Valid CompanyCodeReq companyCodeReq,
 BindingResult result, HttpServletResponse response) {

        // 处理 Validator 出错的情况
        if(result.hasErrors()){
            Map<String, Object> errorMap = ResponseUtil.buildFieldBindErrorMap(result.getFieldError().getDefaultMessage());
            response.addHeader(SDKConstant.NOT_TRANSFORM_BODY, HttpStatus.BAD_REQUEST.toString());
            return ResponseEntity.badRequest().body(errorMap);
        }
        CompanyCodeResp searchResult = companyApiService.getCodeSearchResult();

        return new ResponseEntity<>(searchResult, HttpStatus.OK);
    }


  1. 在Controller 中获取 BindingResult 的结果,并在其中获取出错的消息,返回异常的结果
  2. ResponseEntity.badRequest().body(errorMap) ,这个方法就可以放回指定的结果了,这里设置了 header,用于上面的 ControllerAdvice 做过滤使用。
参数错误等校验异常处理
@RequestMapping(path = "/error", produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
    @ResponseBody
    public Map<String, Object> handle(HttpServletRequest request) {

        Map<String, Object> map = new HashMap<>();
        map.put("errorCode",request.getAttribute("javax.servlet.error.status_code"));
        if (StringUtils.isNoneBlank(request.getAttribute("javax.servlet.error.message").toString())) {
            map.put("message", request.getAttribute("javax.servlet.error.message"));
        } else {
            map.put("message", "请求参数或方法错误");
        }
        map.put("data", null);
        return map;
    }

这个就相当于 做 Spring MVC 的时候,View 的功能

<error-page>
    <location>/error</location>
</error-page>

参考

spring doc

转载于:https://my.oschina.net/tigerlene/blog/1068889

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值