全网整合营销服务商

电脑端+手机端+微信端=数据同步管理

免费咨询热线:400-708-3566

SpringBoot初始教程之统一异常处理详解

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小时内与您取得联系。