@RestControllerAdvice作用及原理
原文:Spring Boot 系列(八)@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。
原文地址:https://www.cnblogs.com/UncleWang001/p/10949318.html
@RestControllerAdvice作用及原理的更多相关文章
- if __name__ == 'main': 的作用和原理
if __name__ == 'main': 功能 一个python的文件有两种使用的方法,第一是直接作为脚本执行,第二是import到其他的python脚本中被调用(模块重用)执行. if __na ...
- 【原创】uC/OS 中LES BX,DWORD PTR DS:_OSTCBCur的作用及原理
LES BX, DWORD PTR DS:_OSTCBCur ;OSTCBCur->OSTCBStkPtr = SS:SP!!! ], SS ;将当前SS(栈的基地址)寄存器值存放至当前任务控制 ...
- synchronized与volatile的区别及各自的作用、原理(学习记录)
synchronized与volatile的区别,它们的作用及原理? 说到两者的区别,先要了解锁提供的两种特性:互斥(mutual exclusion) 和可见性(visibility). 互斥:即一 ...
- volatile关键字的作用、原理
在只有双重检查锁,没有volatile的懒加载单例模式中,由于指令重排序的问题,我确实不会拿到两个不同的单例了,但我会拿到"半个"单例. 而发挥神奇作用的volatile,可以当之 ...
- 面试题:volatile关键字的作用、原理
在只有双重检查锁,没有volatile的懒加载单例模式中,由于指令重排序的问题,我确实不会拿到两个不同的单例了,但我会拿到“半个”单例. 而发挥神奇作用的volatile,可以当之无愧的被称为Java ...
- JAVA基础加强(张孝祥)_类加载器、分析代理类的作用与原理及AOP概念、分析JVM动态生成的类、实现类似Spring的可配置的AOP框架
1.类加载器 ·简要介绍什么是类加载器,和类加载器的作用 ·Java虚拟机中可以安装多个类加载器,系统默认三个主要类加载器,每个类负责加载特定位置的类:BootStrap,ExtClassLoader ...
- wpf Content数据绑定StringFormat起作用的原理和解决
原文:wpf Content数据绑定StringFormat起作用的原理和解决 <Window x:Class="WpfOne.Bind.Bind6" xmlns=" ...
- java.lang.ThreadLocal的作用和原理?列举在哪些程序中见过ThreadLocal的使用?
java.lang.ThreadLocal的作用和原理?列举在哪些程序中见过ThreadLocal的使用? 说明类java.lang.ThreadLocal的作用和原理.列举在哪些程序中见过Threa ...
- 【面试题】为什么有时用Vue.use()?及Vue.use()的作用及原理是什么?
Vue.use()的作用及原理 点击打开视频讲解 在Vue中引入使用第三方库通常我们都会采用import的形式引入进来 但是有的组件在引入之后又做了Vue.use()操作 有的组件引入进来又进行了Vu ...
随机推荐
- DataList做一个相册,并可以上传图片
1.前台代码 <%@ Page Language="C#" AutoEventWireup="true" CodeBehind="DataLis ...
- C++之控制内存分配
一.内存分配方式 在C++中,内存分成5个区,他们分别是堆.栈.自由存储区.全局/静态存储区和常量存储区.栈:在执行函数时,函数内局部变量的存储单元都可以在栈上创建,函数执行结束时这些存储单元自动被释 ...
- Python学习笔记(三)——文件系统中的常用方法
OS模块中关于文件/目录常用的函数使用方法 函数名 使用方法 getcwd() 返回当前工作目录 chdir() 改变工作目录 listdir(path='.') 列举指定目录中的文件名('.'表示当 ...
- 微信公众号开发API接口大全
在本文中,我们列出微信公众平台上可以使用的API接口以及举例如何在微信公众平台调用这些接口实现相应的功能. 接口调用说明: ① Appkey请使用的微信公众号,不要使用默认的trailuser ② 接 ...
- 页面JS缓存问题解决方案
.在jsp中加入头 <META HTTP-EQUIV="Pragma" CONTENT="no-cache"> <META HTTP-EQUI ...
- Unable to find explicit activity class报错问题解决方法
转:http://hi.baidu.com/mz_mz/item/f5672ad814e1ce30e2108f69 1.首先查看是否在已经在AndroidMainfest.xml中添加了你的Activ ...
- 16.ajax_case08
# 抓取简书博客总阅读量 # https://www.jianshu.com/u/130f76596b02 import requests import json import re from lxm ...
- springboot新手脱坑之无法下载依赖包
1. Apache maven 3.39配置 1.环境变量自己配置, 2.配置阿里云镜像和本地仓库 <localRepository>D:\Apache\maven\repository& ...
- Jumpserver-1.5.2 安装步骤
Jumpsever 是飞致云旗下的一块开源的堡垒机.在如今都在上云的趋势下,一款堡垒机非常重要. 官网:http://jumpserver.org/ GitHub:https://github.com ...
- Ubuntu环境下Error: Invalid or corrupt jarfile xxx.jar
一.问题描述 Ubuntu环境下将Maven项目打包成jar包后,运行一下指令: $ java -jar my.jar 发生错误: Error: Invalid or corrupt jarfile ...