SpringBoot @ControllerAdvice 拦截异常并统一处理

在spring 3.2中,新增了@ControllerAdvice 注解,可以用于定义@ExceptionHandler、@InitBinder、@ModelAttribute,并应用到所有@RequestMapping中。参考:@ControllerAdvice 文档

一、介绍

创建 MyControllerAdvice,并添加 @ControllerAdvice注解。

package com.sam.demo.controller;

import org.springframework.ui.Model;
import org.springframework.web.bind.WebDataBinder;
import org.springframework.web.bind.annotation.*;
import java.util.HashMap;
import java.util.Map;

/**
 * controller 增强器
 * @author sam
 * @since 2017/7/17
 */
@ControllerAdvice
public class MyControllerAdvice {

 /**
  * 应用到所有@RequestMapping注解方法,在其执行之前初始化数据绑定器
  * @param binder
  */
 @InitBinder
 public void initBinder(WebDataBinder binder) {}

 /**
  * 把值绑定到Model中,使全局@RequestMapping可以获取到该值
  * @param model
  */
 @ModelAttribute
 public void addAttributes(Model model) {
  model.addAttribute("author", "Magical Sam");
 }

 /**
  * 全局异常捕捉处理
  * @param ex
  * @return
  */
 @ResponseBody
 @ExceptionHandler(value = Exception.class)
 public Map errorHandler(Exception ex) {
  Map map = new HashMap();
  map.put("code", 100);
  map.put("msg", ex.getMessage());
  return map;
 }

}

启动应用后,被 @ExceptionHandler、@InitBinder、@ModelAttribute 注解的方法,都会作用在 被 @RequestMapping 注解的方法上。

@ModelAttribute:在Model上设置的值,对于所有被 @RequestMapping 注解的方法中,都可以通过 ModelMap 获取,如下:

@RequestMapping("/home")
public String home(ModelMap modelMap) {
 System.out.println(modelMap.get("author"));
}

//或者 通过@ModelAttribute获取

@RequestMapping("/home")
public String home(@ModelAttribute("author") String author) {
 System.out.println(author);
}

@ExceptionHandler 拦截了异常,我们可以通过该注解实现自定义异常处理。其中,@ExceptionHandler 配置的 value 指定需要拦截的异常类型,上面拦截了 Exception.class 这种异常。

二、自定义异常处理(全局异常处理)

spring boot 默认情况下会映射到 /error 进行异常处理,但是提示并不十分友好,下面自定义异常处理,提供友好展示。

1、编写自定义异常类:

package com.sam.demo.custom;

/**
 * @author sam
 * @since 2017/7/17
 */
public class MyException extends RuntimeException {

 public MyException(String code, String msg) {
  this.code = code;
  this.msg = msg;
 }

 private String code;
 private String msg;

 // getter & setter
}

注:spring 对于 RuntimeException 异常才会进行事务回滚。

2、编写全局异常处理类

创建 MyControllerAdvice.java,如下:

package com.sam.demo.controller;

import org.springframework.ui.Model;
import org.springframework.web.bind.WebDataBinder;
import org.springframework.web.bind.annotation.*;

import java.util.HashMap;
import java.util.Map;

/**
 * controller 增强器
 *
 * @author sam
 * @since 2017/7/17
 */
@ControllerAdvice
public class MyControllerAdvice {

 /**
  * 全局异常捕捉处理
  * @param ex
  * @return
  */
 @ResponseBody
 @ExceptionHandler(value = Exception.class)
 public Map errorHandler(Exception ex) {
  Map map = new HashMap();
  map.put("code", 100);
  map.put("msg", ex.getMessage());
  return map;
 }

 /**
  * 拦截捕捉自定义异常 MyException.class
  * @param ex
  * @return
  */
 @ResponseBody
 @ExceptionHandler(value = MyException.class)
 public Map myErrorHandler(MyException ex) {
  Map map = new HashMap();
  map.put("code", ex.getCode());
  map.put("msg", ex.getMsg());
  return map;
 }

}

3、controller中抛出异常进行测试。

@RequestMapping("/home")
public String home() throws Exception {

//  throw new Exception("Sam 错误");
 throw new MyException("101", "Sam 错误");

}

启动应用,访问:http://localhost:8080/home ,正常显示以下json内容,证明自定义异常已经成功被拦截。

{"msg":"Sam 错误","code":"101"}

* 如果不需要返回json数据,而要渲染某个页面模板返回给浏览器,那么MyControllerAdvice中可以这么实现:

@ExceptionHandler(value = MyException.class)
public ModelAndView myErrorHandler(MyException ex) {
 ModelAndView modelAndView = new ModelAndView();
 modelAndView.setViewName("error");
 modelAndView.addObject("code", ex.getCode());
 modelAndView.addObject("msg", ex.getMsg());
 return modelAndView;
}

在 templates 目录下,添加 error.ftl(这里使用freemarker) 进行渲染:

<!DOCTYPE html>
<html lang="en">
<head>
 <meta charset="UTF-8">
 <title>错误页面</title>
</head>
<body>
 <h1>$[code]</h1>
 <h1>${msg}</h1>
</body>
</html>

重启应用,http://localhost:8080/home 显示自定的错误页面内容。

补充:如果全部异常处理返回json,那么可以使用 @RestControllerAdvice 代替 @ControllerAdvice ,这样在方法上就可以不需要添加 @ResponseBody。

到此这篇关于SpringBoot @ControllerAdvice 拦截异常并统一处理的文章就介绍到这了,更多相关SpringBoot @ControllerAdvice 拦截异常内容请搜索我们以前的文章或继续浏览下面的相关文章希望大家以后多多支持我们!

(0)

相关推荐

  • SpringBoot逻辑异常统一处理方法

    这篇文章主要介绍了SpringBoot逻辑异常统一处理方法,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下 构建项目 我们将逻辑异常核心处理部分提取出来作为单独的jar供其他模块引用,创建项目在parent项目pom.xml添加公共使用的依赖,配置内容如下所示: <dependencies> <!--Lombok--> <dependency> <groupId>org.projectlombok</g

  • SpringBoot使用统一异常处理详解

    场景:针对异常处理,我们原来的做法是一般在最外层捕获异常即可,例如在Controller中 @Controller public class HelloController { private static final Logger logger = LoggerFactory.getLogger(HelloController.class); @GetMapping(value = "/hello") @ResponseBody public Result hello() { try

  • SpringBoot集成Beetl后统一处理页面异常的方法

    背景 SpringBoot集成Beetl后如果页面出现异常会将出现异常之前的页面输出到客户端,但是由于页面不完整会导致用户看到的页面错乱或者空白,如下 <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> </head> <body> 在控制台可以看到 >

  • SpringBoot处理全局统一异常的实现

    在后端发生异常或者是请求出错时,前端通常显示如下 Whitelabel Error Page This application has no explicit mapping for /error, so you are seeing this as a fallback. Fri Jun 07 15:38:07 CST 2019 There was an unexpected error (type=Not Found, status=404). No message available 对于

  • SpringBoot 2 统一异常处理过程解析

    统一异常处理相关注解介绍 @ControllerAdvice 声明在类上用于指定该类为控制增强器类,如果想声明返回的结果为 RESTFull 风格的数据,需要在声明 @ExceptionHandler 注解的方法上同时加 上 @ResponseBody @RestControllerAdvice 声明在类上用于指定该类为控制增强器类.并声明返回的结果为 RESTFull 风格的数据,无需在声明@ExceptionHandler 注解的方法上加@ResponseBody @ExceptionHan

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

    1.介绍 在日常开发中发生了异常,往往是需要通过一个统一的异常处理处理所有异常,来保证客户端能够收到友好的提示.SpringBoot在页面发生异常的时候会自动把请求转到/error,SpringBoot内置了一个BasicErrorController对异常进行统一的处理,当然也可以自定义这个路径 application.yaml server: port: 8080 error: path: /custom/error BasicErrorController提供两种返回错误一种是页面返回.当

  • SpringBoot 统一异常处理详解

    代码结构 配置pom文件 <?xml version="1.0" encoding="UTF-8"?> <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/

  • SpringBoot @ControllerAdvice 拦截异常并统一处理

    在spring 3.2中,新增了@ControllerAdvice 注解,可以用于定义@ExceptionHandler.@InitBinder.@ModelAttribute,并应用到所有@RequestMapping中.参考:@ControllerAdvice 文档 一.介绍 创建 MyControllerAdvice,并添加 @ControllerAdvice注解. package com.sam.demo.controller; import org.springframework.ui

  • SpringBoot搭建全局异常拦截

    1.异常拦截类的创建 package com.liqi.web.core.exception; import org.springframework.web.bind.annotation.ExceptionHandler; import org.springframework.web.bind.annotation.ResponseBody; import org.springframework.web.bind.annotation.RestControllerAdvice; import

  • springboot实现拦截器的3种方式及异步执行的思考

    目录 springboot 拦截器 springboot 入门案例 maven 引入 启动类 定义 Controller 拦截器定义 基于 Aspect 基于 HandlerInterceptor 基于 ResponseBodyAdvice 测试 异步执行 定义异步线程池 异步执行的 Controller 思考 测试 反思 springboot 拦截器 实际项目中,我们经常需要输出请求参数,响应结果,方法耗时,统一的权限校验等. 本文首先为大家介绍 HTTP 请求中三种常见的拦截实现,并且比较一

  • SpringBoot切面拦截@PathVariable参数及抛出异常的全局处理方式

    目录 SpringBoot切面拦截@PathVariable参数及抛出异常的全局处理 例如: 为了方便统一验证,基于切面来实现数据的验证 全局异常处理 异常原因: java.lang.reflect.UndeclaredThrowableException的解决 问题 原因 解决 教训 SpringBoot切面拦截@PathVariable参数及抛出异常的全局处理 微信小程序的接口验证防止非法请求,登录的时候获取openId生成一个七天有效期token存入redis中. 后续每次请求都需要把to

  • 关于springboot的接口返回值统一标准格式

    目录 一.目标 二.为什么要对springboot的接口返回值统一标准格式? 第一种格式:response为String 第二种格式:response为Objct 第三种格式:response为void 第四种格式:response为异常 三.定义response的标准格式 四.初级程序员对response代码封装 步骤1:把标准格式转换为代码 步骤2:把状态码存在枚举类里面 步骤3:加一个体验类 五.高级程序员对response代码封装 步骤1:采用ResponseBodyAdvice技术来实

  • SpringBoot异步方法捕捉异常详解

    本文实例为大家分享了SpringBoot异步方法捕捉异常的具体代码,供大家参考,具体内容如下 由于项目中定时器都采用异步执行方式 需要定时监控异步方法执行进度,异常情况 1 执行进度 可以设置是否在执行,内存中添加执行标识即可. 防止多次执行可以通过拦截器对此,标识来判断,防止多次执行定时器 2 异常捕捉 监控异步方法执行是否异常. 1 无返回值 配置AsyncExceptionConfig类,统一处理. 定义异常捕获配置类AsyncExceptionConfig,配置类里面定义SpringAs

  • Spring MVC Controller返回值及异常的统一处理方法

    旧的设计方案 开发api的时候,需要先定义好接口的数据响应结果.如下是一个很简单直接的Controller实现方法及响应结果定义. @RestController @RequestMapping("/users") public class UserController { @Inject private UserService userService; @GetRequest("/{userId:\\d+}") public ResponseBean signin

  • SpringBoot登录拦截配置详解(实测可用)

    背景:写一个用户登录拦截,在网上找了一圈没找到好用的,于是自己试验了一下,总结出来,分享给大家. 1.自定义登录拦截器LoginInterceptor public class LoginInterceptor implements HandlerInterceptor { @Override public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) thr

  • SpringBoot中定制异常页面的实现方法

    定制异常页面,可以避免用户产生恐慌心理,使得产品有更好的用户体验.今天来学习在 SpringBoot 中如何定制开发异常页面 一.历史回顾 在 SpringMVC 年代,我们的异常页面一般配置在 web.xml 文件中,如下: <!-- 配置404页面 --> <error-page> <error-code>404</error-code> <location>/error/404.html</location> </erro

  • 教你用Springboot实现拦截器获取header内容

    分析 既然需要动态获取那么只有两种方式:要么每次下游请求过来时从请求头中获取,要么定义统一的拦截器自动获取. 实现 那么我们就先来实现一下吧. 第一种比较简单,直接使用springboot获取请求头的方式,从controller方法入口处使用: @RequestHeader(value = "xxxx",required = false) String appUser的方式获取请求头 代码如下: @RequestMapping(name = "获取用户详情信息",v

随机推荐