1.介绍

在日常开发中发生了异常,往往是需要通过一个统一的异常处理处理所有异常,来保证客户端能够收到友好的提示。SpringBoot在页面发生异常的时候会自动把请求转到/error,SpringBoot内置了一个BasicErrorController对异常进行统一的处理,当然也可以自定义这个路径
application.yaml
server: port: 8080 error: path: /custom/error
BasicErrorController提供两种返回错误一种是页面返回、当你是页面请求的时候就会返回页面,另外一种是json请求的时候就会返回json错误
@RequestMapping(produces = "text/html")
public ModelAndView errorHtml(HttpServletRequest request,
HttpServletResponse response) {
HttpStatus status = getStatus(request);
Map<String, Object> model = Collections.unmodifiableMap(getErrorAttributes(
request, isIncludeStackTrace(request, MediaType.TEXT_HTML)));
response.setStatus(status.value());
ModelAndView modelAndView = resolveErrorView(request, response, status, model);
return (modelAndView == null ? new ModelAndView("error", model) : modelAndView);
}
@RequestMapping
@ResponseBody
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<Map<String, Object>>(body, status);
}
分别会有如下两种返回
{
"timestamp": 1478571808052,
"status": 404,
"error": "Not Found",
"message": "No message available",
"path": "/rpc"
}
2.通用Exception处理
通过使用@ControllerAdvice来进行统一异常处理,@ExceptionHandler(value = Exception.class)来指定捕获的异常
下面针对两种异常进行了特殊处理分别返回页面和json数据,使用这种方式有个局限,无法根据不同的头部返回不同的数据格式,而且无法针对404、403等多种状态进行处理
@ControllerAdvice
public class GlobalExceptionHandler {
public static final String DEFAULT_ERROR_VIEW = "error";
@ExceptionHandler(value = CustomException.class)
@ResponseBody
public ResponseEntity defaultErrorHandler(HttpServletRequest req, CustomException e) throws Exception {
return ResponseEntity.ok("ok");
}
@ExceptionHandler(value = Exception.class)
public ModelAndView defaultErrorHandler(HttpServletRequest req, Exception e) throws Exception {
ModelAndView mav = new ModelAndView();
mav.addObject("exception", e);
mav.addObject("url", req.getRequestURL());
mav.setViewName(DEFAULT_ERROR_VIEW);
return mav;
}
}
3.自定义BasicErrorController 错误处理
在初始介绍哪里提到了BasicErrorController,这个是SpringBoot的默认错误处理,也是一种全局处理方式。咱们可以模仿这种处理方式自定义自己的全局错误处理
下面定义了一个自己的BasicErrorController,可以根据自己的需求自定义errorHtml()和error()的返回值。
@Controller
@RequestMapping("${server.error.path:${error.path:/error}}")
public class BasicErrorController extends AbstractErrorController {
private final ErrorProperties errorProperties;
private static final Logger LOGGER = LoggerFactory.getLogger(BasicErrorController.class);
@Autowired
private ApplicationContext applicationContext;
/**
* Create a new {@link org.springframework.boot.autoconfigure.web.BasicErrorController} instance.
*
* @param errorAttributes the error attributes
* @param errorProperties configuration properties
*/
public BasicErrorController(ErrorAttributes errorAttributes,
ErrorProperties errorProperties) {
this(errorAttributes, errorProperties,
Collections.<ErrorViewResolver>emptyList());
}
/**
* Create a new {@link org.springframework.boot.autoconfigure.web.BasicErrorController} instance.
*
* @param errorAttributes the error attributes
* @param errorProperties configuration properties
* @param errorViewResolvers error view resolvers
*/
public BasicErrorController(ErrorAttributes errorAttributes,
ErrorProperties errorProperties, List<ErrorViewResolver> errorViewResolvers) {
super(errorAttributes, errorViewResolvers);
Assert.notNull(errorProperties, "ErrorProperties must not be null");
this.errorProperties = errorProperties;
}
@Override
public String getErrorPath() {
return this.errorProperties.getPath();
}
@RequestMapping(produces = "text/html")
public ModelAndView errorHtml(HttpServletRequest request,
HttpServletResponse response) {
HttpStatus status = getStatus(request);
Map<String, Object> model = Collections.unmodifiableMap(getErrorAttributes(
request, isIncludeStackTrace(request, MediaType.TEXT_HTML)));
response.setStatus(status.value());
ModelAndView modelAndView = resolveErrorView(request, response, status, model);
insertError(request);
return modelAndView == null ? new ModelAndView("error", model) : modelAndView;
}
@RequestMapping
@ResponseBody
public ResponseEntity<Map<String, Object>> error(HttpServletRequest request) {
Map<String, Object> body = getErrorAttributes(request,
isIncludeStackTrace(request, MediaType.ALL));
HttpStatus status = getStatus(request);
insertError(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 = getErrorProperties().getIncludeStacktrace();
if (include == ErrorProperties.IncludeStacktrace.ALWAYS) {
return true;
}
if (include == ErrorProperties.IncludeStacktrace.ON_TRACE_PARAM) {
return getTraceParameter(request);
}
return false;
}
/**
* Provide access to the error properties.
*
* @return the error properties
*/
protected ErrorProperties getErrorProperties() {
return this.errorProperties;
}
}
SpringBoot提供了一种特殊的Bean定义方式,可以让我们容易的覆盖已经定义好的Controller,原生的BasicErrorController是定义在ErrorMvcAutoConfiguration中的
具体代码如下:
@Bean
@ConditionalOnMissingBean(value = ErrorController.class, search = SearchStrategy.CURRENT)
public BasicErrorController basicErrorController(ErrorAttributes errorAttributes) {
return new BasicErrorController(errorAttributes, this.serverProperties.getError(),
this.errorViewResolvers);
}
可以看到这个注解@ConditionalOnMissingBean 意思就是定义这个bean 当 ErrorController.class 这个没有定义的时候, 意思就是说只要我们在代码里面定义了自己的ErrorController.class时,这段代码就不生效了,具体自定义如下:
@Configuration
@ConditionalOnWebApplication
@ConditionalOnClass({Servlet.class, DispatcherServlet.class})
@AutoConfigureBefore(WebMvcAutoConfiguration.class)
@EnableConfigurationProperties(ResourceProperties.class)
public class ConfigSpringboot {
@Autowired(required = false)
private List<ErrorViewResolver> errorViewResolvers;
private final ServerProperties serverProperties;
public ConfigSpringboot(
ServerProperties serverProperties) {
this.serverProperties = serverProperties;
}
@Bean
public MyBasicErrorController basicErrorController(ErrorAttributes errorAttributes) {
return new MyBasicErrorController(errorAttributes, this.serverProperties.getError(),
this.errorViewResolvers);
}
}
在使用的时候需要注意MyBasicErrorController不能被自定义扫描Controller扫描到,否则无法启动。
3.总结
一般来说自定义BasicErrorController这种方式比较实用,因为可以通过不同的头部返回不同的数据格式,在配置上稍微复杂一些,但是从实用的角度来说比较方便而且可以定义通用组件
本文代码:SpringBoot-Learn_jb51.rar
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持。
# spring
# boot
# 统一异常
# 统一异常处理
# 如何在SpringBoot项目里进行统一异常处理
# SpringBoot接口如何统一异常处理
# SpringBoot中如何进行统一异常处理
# SpringBoot 2 统一异常处理过程解析
# SpringBoot 统一异常处理详解
# SpringBoot项目实现统一异常处理的最佳方案
# 自定义
# 自己的
# 两种
# 就会
# 数据格式
# 会有
# 你是
# 有个
# 让我们
# 就不
# 这段
# 转到
# 可以通过
# 可以看到
# 生了
# 可以根据
# 需要注意
# 大家多多
# 中发
# 进行了
相关文章:
外汇网站制作流程,如何在工商银行网站上做外汇买卖?
建站之星如何实现PC+手机+微信网站五合一建站?
微网站制作教程,不会写代码,不会编程,怎么样建自己的网站?
h5在线制作网站电脑版下载,h5网页制作软件?
南京网站制作费用,南京远驱官方网站?
建站之星代理商如何保障技术支持与售后服务?
已有域名如何免费搭建网站?
制作网站的网址是什么,请问后缀为.com和.com.cn还有.cn的这三种网站是分别是什么类型的网站?
如何制作公司的网站链接,公司想做一个网站,一般需要花多少钱?
网站制作专业公司有哪些,如何制作一个企业网站,建设网站的基本步骤有哪些?
建站之星与建站宝盒如何选择最佳方案?
实现虚拟支付需哪些建站技术支撑?
如何在IIS中配置站点IP、端口及主机头?
如何在Golang中引入测试模块_Golang测试包导入与使用实践
品牌网站制作公司有哪些,买正品品牌一般去哪个网站买?
北京制作网站的公司,北京铁路集团官方网站?
如何通过IIS搭建网站并配置访问权限?
c++ stringstream用法详解_c++字符串与数字转换利器
山东网站制作公司有哪些,山东大源集团官网?
建站之星备案是否影响网站上线时间?
如何用低价快速搭建高质量网站?
如何自定义建站之星网站的导航菜单样式?
兔展官网 在线制作,怎样制作微信请帖?
免费网站制作模板下载,除了易企秀之外还有什么H5平台可以制作H5长页面,最好是免费的?
如何通过虚拟主机空间快速建站?
网站制作网站,深圳做网站哪家比较好?
免费公司网站制作软件,如何申请免费主页空间做自己的网站?
网站图片在线制作软件,怎么在图片上做链接?
家族网站制作贴纸教程视频,用豆子做粘帖画怎么制作?
宝塔面板创建网站无法访问?如何快速排查修复?
c# F# 的 MailboxProcessor 和 C# 的 Actor 模型
建站之星CMS五站合一模板配置与SEO优化指南
专业网站建设制作报价,网页设计制作要考什么证?
视频网站制作教程,怎么样制作优酷网的小视频?
如何制作网站标识牌,动态网站如何制作(教程)?
如何通过cPanel快速搭建网站?
c# 服务器GC和工作站GC的区别和设置
济南网站建设制作公司,室内设计网站一般都有哪些功能?
如何挑选最适合建站的高性能VPS主机?
如何高效利用200m空间完成建站?
如何配置支付宝与微信支付功能?
金*站制作公司有哪些,金华教育集团官网?
济南专业网站制作公司,济南信息工程学校怎么样?
Swift中循环语句中的转移语句 break 和 continue
如何在服务器上三步完成建站并提升流量?
ppt在线制作免费网站推荐,有什么下载免费的ppt模板网站?
郑州企业网站制作公司,郑州招聘网站有哪些?
制作电商网页,电商供应链怎么做?
c# await 一个已经完成的Task会发生什么
,柠檬视频怎样兑换vip?
*请认真填写需求信息,我们会在24小时内与您取得联系。