热爱技术,追求卓越
不断求索,精益求精

springboot统一异常处理及Whitelabel Error Page返回json屏蔽null字段

springboot返回json格式而非Whitelabel Error Page页面

我们使用springboot做API网关,提供rest接口的时候,如果请求的接口没有实现,springboot默认情况下返回如下的页面:

Whitelabel Error Page
This application has no explicit mapping for /error, so you are seeing this as a fallback.

Wed Jan 16 11:45:32 CST 2019
There was an unexpected error (type=Not Found, status=404).
No message available

API网关建议统一返回json数据格式如下:

{"code":1,"message":"success","time":1547610575320,"body":"hello"}

如果我们没有实现对应的接口,就会出现上面的“Whitelabel Error Page”的错误html页面,而不是返回的json格式。

解决办法是在应用配置文件,如“application.properties”中加入如下配置:

spring.mvc.throw-exception-if-no-handler-found=true
spring.resources.add-mappings=false

上面还不够,我们还要使用“@ControllerAdvice”实现统一异常处理。

@ControllerAdvice实现统一异常处理

先来看看统一返回序列化为json的类Result:

public class Result<T> {
    /** 自定义状态码 */
    private Integer code;
    /** 状态码对应的提示信息 */
    private String message;
    /** 当前时间用于前台,因为前台时间不准确 */
    private Long time = System.currentTimeMillis();
    /** 返回体 */
    private T body;
}

定义一个API网关层运行时异常类GatewayException:

public class GatewayException extends RuntimeException{

    private static final long serialVersionUID = 1L;
    /**错误码*/
    private Integer errorCode;
    /**错误消息*/
    private String errorMessage;
}

使用注解“@ControllerAdvice”实现统一异常处理类:

import javax.servlet.http.HttpServletResponse;

import org.springframework.http.HttpStatus;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;
import org.springframework.web.servlet.NoHandlerFoundException;

import cn.lovecto.common.bean.Result;
import cn.lovecto.common.exception.GatewayException;

@ControllerAdvice
@ResponseBody
public class BaseExceptionDemo {

    /**
     * 统一异常处理
     * 
     * @param e
     * @return
     */
    @ExceptionHandler({ Exception.class })
    public Result<?> processException(Exception e) {
        HttpServletResponse response = ((ServletRequestAttributes) RequestContextHolder
                .getRequestAttributes()).getResponse();
        // 默认返回200状态码
        response.setStatus(HttpStatus.OK.value());
        Result<?> result = null;
        if (e instanceof NoHandlerFoundException) {// 处理404
            response.setStatus(HttpStatus.NOT_FOUND.value());
            result = new Result<String>(HttpStatus.NOT_FOUND.value(),
                    "Client Error");
        } else if (e instanceof GatewayException) {// 网关层自定义的异常明确抛出
            GatewayException gatewayException = (GatewayException) e;
            result = new Result<String>(gatewayException.getErrorCode(),
                    gatewayException.getErrorMessage());
        } else {// 其他异常,返回500状态码
            response.setStatus(HttpStatus.INTERNAL_SERVER_ERROR.value());
            result = new Result<String>(
                    HttpStatus.INTERNAL_SERVER_ERROR.value(),
                    "Internal Server Error");
        }
        return result;
    }

}

创建一个TestController用于模拟以上场景:

@RestController
@RequestMapping(value = "/test")
public class TestController extends BaseController {

    @GetMapping("/hello")
    public Result<String> basicHello() {
        return new Result<String>(ErrorCodeEnum.SUCCESS, "hello");
    }

    @GetMapping("/error")
    public Result<Boolean> error() {
        throw new GatewayException(0, "自定义错误");
    }
}

访问:http://localhost:8080/test/hello
http状态码为200:

{"code":1,"message":"success","time":1547618674710,"body":"hello"}

访问:http://localhost:8080/test/error
http状态码为200:

{"code":0,"message":"自定义错误","time":1547618775715,"body":null}

访问不存在的url:http://localhost:8080/test/xxx
http状态码为404:

{"code":404,"message":"Client Error","time":1547618821473,"body":null}

处理返回的json里面包含了null字段的情况

看到上面返回的body是null,有时候我们为了减少数据传输,没必要把值为null的对象序列化到json里,所以需要在配置,如“application.properties”加入如下配置(全局配置方式):

spring.jackson.default-property-inclusion=non_null

如果不是全局配置,可以在对应的类属性上加注解方式:

@JsonInclude(JsonInclude.Include.NON_NULL)
赞(5)
未经允许不得转载:LoveCTO » springboot统一异常处理及Whitelabel Error Page返回json屏蔽null字段

评论 抢沙发

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址

热爱技术 追求卓越 精益求精