详解Springboot自定义异常处理

网友投稿 333 2023-05-25


详解Springboot自定义异常处理

背景

Springboot 默认把异常的处理集中到一个ModelAndView中了,但项目的实际过程中,这样做,并不能满足我们的要求。具体的自定义异常的处理,参看以下

具体实现

如果仔细看完spring boot的异常处理详解,并且研究过源码后,我觉得具体的实现可以不用看了。。。

重写定义错误页面的url,默认只有一个/error

@Bean

public EmbeddedServletContainerCustomizer containerCustomizer(){

return new EmbeddedServletContainerCustomizer(){

@Override

public vUTagUvnVBJoid customize(ConfigurableEmbeddedServletContainer container) {

container.addErrorPages(new ErrorPage(HttpStatus.NOT_FOUND, "/error/404"));

container.addErrorPages(new ErrorPage(HttpStatus.INTERNAL_SERVER_ERROR, "/error/500"));

container.addErrorPages(new ErrorPage(java.lang.Throwable.class,"/error/500"));

}

};

}

重写通过实现ErrorController,重写BasicErrorController的功能实现

/**

* 重写BasicErrorController,主要负责系统的异常页面的处理以及错误信息的显示

* @see org.springframework.boot.autoconfigure.web.BasicErrorController

* @see org.springframework.boot.autoconfigure.web.ErrorMvcAutoConfiguration

*

* @author Jonathan

* @version 2016/5/31 11:22

* @since JDK 7.0+

*/

@Controller

@RequestMapping(value = "error")

@EnableConfigurationProperties({ServerProperties.class})

public class ExceptionController implements ErrorController {

private ErrorAttributes errorAttributes;

@Autowired

private ServerProperties serverProperties;

/**

* 初始化ExceptionController

* @param errorAttributes

*/

@Autowired

public ExceptionController(ErrorAttributes errorAttributes) {

Assert.notNull(errorAttributes, "ErrorAttributes must not be null");

this.errorAttributes = errorAttributes;

}

/**

* 定义404的ModelAndView

* @param request

* @param response

* @return

*/

@RequestMapping(produces = "text/html",value = "404")

public ModelAndView errorHtml404(HttpServletRequest request,

HttpServletResponse response) {

response.setStatus(getStatus(request).value());

Map model = getErrorAttributes(request,

isIncludeStackTrace(request, MediaType.TEXT_HTML));

return new ModelAndView("error/404", model);

}

/**

* 定义404的jsON数据

* @param request

* @return

*/

@RequestMapping(value = "404")

@ResponseBody

public ResponseEntity> error404(HttpServletRequest request) {

Map body = getErrorAttributes(request,

isIncludeStackTrace(request, MediaType.TEXT_HTML));

HttpStatus status = getStatus(request);

return new ResponseEntity>(body, status);

}

/**

* 定义500的ModelAndView

* @param request

* @param response

* @return

*/

@RequestMapping(produces = "text/html",value = "500")

public ModelAndView errorHtml500(HttpServletRequest request,

HttpServletResponse response) {

response.setStatus(getStatus(request).value());

Map model = getErrorAttributes(request,

isIncludeStackTrace(request, MediaType.TEXT_HTML));

return new ModelAndView("error/500", model);

}

/**

* 定义500的错误JSON信息

* @param request

* @return

*/

@RequestMapping(value = "500")

@ResponseBody

public ResponseEntity> error500(HttpServletRequest request) {

Map body = getErrorAttributes(request,

isIncludeStackTrace(request, MediaType.TEXT_HTML));

HttpStatus status = getStatus(request);

return new ResponseEntity>(body, status);

}

/**

* Determine if the stacktrace attribute should be included.

* @param request the source request

* @param produces the media type produced (or {@code MediaType.ALL})

* @return if the stacktrace attribute should be included

*/

protected boolean isIncludeStackTrace(HttpServletRequest request,

MediaType produces) {

ErrorProperties.IncludeStacktrace include = this.serverProperties.getError().getIncludeStacktrace();

if (include == ErrorProperties.IncludeStacktrace.ALWAYS) {

return true;

}

if (include == ErrorProperties.IncludeStacktrace.ON_TRACE_PARAM) {

return getTraceParameter(request);

}

return false;

}

/**

* 获取错误的信息

* @param request

* @param includeStackTrace

* @return

*/

private Map getErrorAttributes(HttpServletRequest request,

boolean includeStackTrace) {

RequestAttributes requestAttributes = new ServletReqUTagUvnVBJuestAttributes(request);

return this.errorAttributes.getErrorAttributes(requestAttributes,

includeStackTrace);

}

/**

* 是否包含trace

* @param request

* @return

*/

private boolean getTraceParameter(HttpServletRequest request) {

String parameter = request.getParameter("trace");

if (parameter == null) {

return false;

}

return !"false".equals(parameter.toLowerCase());

}

/**

* 获取错误编码

* @param request

* @return

*/

private HttpStatus getStatus(HttpServletRequest request) {

Integer statusCode = (Integer) request

.getAttribute("javax.servlet.error.status_code");

if (stahttp://tusCode == null) {

return HttpStatus.INTERNAL_SERVER_ERROR;

}

try {

return HttpStatus.valueOf(statusCode);

}

catch (Exception ex) {

return HttpStatus.INTERNAL_SERVER_ERROR;

}

}

/**

* 实现错误路径,暂时无用

* @see ExceptionMvcAutoConfiguration#containerCustomizer()

* @return

*/

@Override

public String getErrorPath() {

return "";

}

}

总结

第一步,通过定义containerCustomizer,重写定义了异常处理对应的视图。目前定义了404和500,可以继续扩展。

第二步,重写BasicErrorController,当然可以直接定义一个普通的controller类,直接实现第一步定义的视图的方法。重写的目的是重用ErrorAttributes。这样在页面,直接可以获取到status,message,exception,trace等内容。

如果仅仅是把异常处理的视图作为静态页面,不需要看到异常信息内容的话,直接第一步后,再定义error/404,error/500等静态视图即可。

ErrorController根据Accept头的内容,输出不同格式的错误响应。比如针对浏览器的请求生成html页面,针对其它请求生成json格式的返回


版权声明:本文内容由网络用户投稿,版权归原作者所有,本站不拥有其著作权,亦不承担相应法律责任。如果您发现本站中有涉嫌抄袭或描述失实的内容,请联系我们jiasou666@gmail.com 处理,核实后本网站将在24小时内删除侵权内容。

上一篇:spring boot下 500 404 错误页面处理的方法
下一篇:详解Spring中Bean的加载的方法
相关文章

 发表评论

暂时没有评论,来抢沙发吧~