Spring Cloud Zuul 错误处理之自定义错误JSON格式(获取出错信息)

spring中错误输出是 org.springframework.boot.autoconfigure.web.servlet.error.BasicErrorController类中error方法输出的。

@RequestMapping
public ResponseEntity<Map<String, Object>> error(HttpServletRequest request) {
    Map<String, Object> body = getErrorAttributes(request,isIncludeStackTrace(request,MediaType.ALL));
    HttpStatus status = getStatus(request);
    return new ResponseEntity<>(body, status);
}
复制代码

getErrorAttributes方法返回的Map包含了错误信息,路径,状态码等信息。

看下方法如何实现的:

protected Map<String, Object> getErrorAttributes(HttpServletRequest request,
			boolean includeStackTrace) {
		WebRequest webRequest = new ServletWebRequest(request);
		return this.errorAttributes.getErrorAttributes(webRequest, includeStackTrace);
}
复制代码

可以看到,他实例化ServletWebRequest并传入getErrorAttributes方法参数中了。

我们看下errorAttributes这个属性是什么

public abstract class AbstractErrorController implements ErrorController {

	private final ErrorAttributes errorAttributes;

	private final List<ErrorViewResolver> errorViewResolvers;
	
	...
}
复制代码

可以看到这是个常量,我们看下类的定义:

public interface ErrorAttributes {

	/**
	 * Returns a {@link Map} of the error attributes. The map can be used as the model of
	 * an error page {@link ModelAndView}, or returned as a {@link ResponseBody}.
	 * @param webRequest the source request
	 * @param includeStackTrace if stack trace elements should be included
	 * @return a map of error attributes
	 */
	Map<String, Object> getErrorAttributes(WebRequest webRequest,
			boolean includeStackTrace);

	/**
	 * Return the underlying cause of the error or {@code null} if the error cannot be
	 * extracted.
	 * @param webRequest the source request
	 * @return the {@link Exception} that caused the error or {@code null}
	 */
	Throwable getError(WebRequest webRequest);

}
复制代码

这个接口定义了两个方法。

getErrorAttributes方法返回了Map集合,从方法文档注释我们可以知道他将出错的信息存储在了这个Map中。

getError返回Throwable类,并且通过文档注释知道这个方法将导致发生错误原因的Throwable返回,并且有可能返回null

那么有了这个接口,我们可以看看它的实现类。

它的默认实现在org.springframework.boot.web.servlet.error.DefaultErrorAttributes这。

/**
 * Default implementation of {@link ErrorAttributes}. Provides the following attributes
 * when possible:
 * <ul>
 * <li>timestamp - The time that the errors were extracted</li>
 * <li>status - The status code</li>
 * <li>error - The error reason</li>
 * <li>exception - The class name of the root exception (if configured)</li>
 * <li>message - The exception message</li>
 * <li>errors - Any {@link ObjectError}s from a {@link BindingResult} exception
 * <li>trace - The exception stack trace</li>
 * <li>path - The URL path when the exception was raised</li>
 * </ul>
 *
 * @author Phillip Webb
 * @author Dave Syer
 * @author Stephane Nicoll
 * @author Vedran Pavic
 * @since 2.0.0
 * @see ErrorAttributes
 */
@Order(Ordered.HIGHEST_PRECEDENCE)
public class DefaultErrorAttributes
		implements ErrorAttributes, HandlerExceptionResolver, Ordered 
复制代码

从这个类的文档注释我们可以知道,他将一些错误信息放在了map中:

  1. timestamp 发生错误的时间
  2. status 状态码
  3. error 错误原因
  4. exception 发生错误的异常类名
  5. message 异常消息
  6. errors 错误信息
  7. trace 异常堆栈信息
  8. path 发生错误的路径

有了这些信息,我们可以定义自己的JSON格式的异常输出了,

但在这之前,我们需要知道这个接口(实现类)是否在IOC容器中有了。

庆幸的是,spring已经帮我们注入了:

 @Bean
public static ErrorMvcAutoConfiguration.PreserveErrorControllerTargetClassPostProcessor preserveErrorControllerTargetClassPostProcessor() {
        return new ErrorMvcAutoConfiguration.PreserveErrorControllerTargetClassPostProcessor();
}
复制代码

那么我们就可以写一个自定义错误处理类了:

package top.itning.server.error.handler;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.web.servlet.error.ErrorAttributes;
import org.springframework.boot.web.servlet.error.ErrorController;
import org.springframework.http.MediaType;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.context.request.ServletWebRequest;
import org.springframework.web.context.request.WebRequest;

import javax.servlet.http.HttpServletRequest;
import java.util.Map;

/**
 * @author itning
 * @date 2019/5/2 18:49
 */
@RestController
public class ErrorHandler implements ErrorController {
    private final ErrorAttributes errorAttributes;

    @Autowired
    public ErrorHandler(ErrorAttributes errorAttributes) {
        this.errorAttributes = errorAttributes;
    }

    @Override
    public String getErrorPath() {
        return "/error";
    }

    @RequestMapping(value = "/error", produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
    public String error(HttpServletRequest request) {
        WebRequest webRequest = new ServletWebRequest(request);
        Map<String, Object> errorAttributes = this.errorAttributes.getErrorAttributes(webRequest, true);
        String msg = errorAttributes.getOrDefault("error", "not found").toString();
        String code = errorAttributes.getOrDefault("status", 404).toString();
        return "{\"code\":" + code + ",\"msg\":\"" + msg + "\",\"data\":\"\"}";
    }
}

复制代码

error方法中,我们返回了JSON格式的自定义错误信息。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值