SpringMVC 中 @ControllerAdvice 注解的三种使用场景!

 

@ControllerAdvice ,很多初学者可能都没有听说过这个注解,实际上,这是一个非常有用的注解,顾名思义,这是一个增强的 Controller。使用这个 Controller ,可以实现三个方面的功能:

  1. 全局异常处理
  2. 全局数据绑定
  3. 全局数据预处理

灵活使用这三个功能,可以帮助我们简化很多工作,需要注意的是,这是 SpringMVC 提供的功能,在 Spring Boot 中可以直接使用,下面分别来看。

全局异常处理

使用 @ControllerAdvice 实现全局异常处理,只需要定义类,添加该注解即可定义方式如下:

@ControllerAdvice
public class MyGlobalExceptionHandler {
@ExceptionHandler(Exception.class)
public ModelAndView customException(Exception e) {
ModelAndView mv = new ModelAndView();
mv.addObject("message", e.getMessage());
mv.setViewName("myerror");
return mv;
}
}

在该类中,可以定义多个方法,不同的方法处理不同的异常,例如专门处理空指针的方法、专门处理数组越界的方法...,也可以直接向上面代码一样,在一个方法中处理所有的异常信息。

@ExceptionHandler 注解用来指明异常的处理类型,即如果这里指定为 NullpointerException,则数组越界异常就不会进到这个方法中来。

import com.house.common.ResponseMessages;
import com.house.controller.Controller1;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseBody; /**
* 统一异常处理
*/
@ControllerAdvice(assignableTypes = {Controller1.class}) //只对Controller1文件做异常处理
//@ControllerAdvice(basePackages = {"cn.myz.demo.controller"}) //指定一个或多个包,这些包及其子包下的所有 Controller 都被该 @ControllerAdvice 管理。
//@ControllerAdvice(basePackageClasses = {MyController1.class}) //指定一个或多个 Controller 类,这些类所属的包及其子包下的所有 Controller 都被该 @ControllerAdvice 管理。
//@ControllerAdvice(assignableTypes = {MyController1.class}) //指定一个或多个 Controller 类,这些类被该 @ControllerAdvice 管理
//@ControllerAdvice(annotations = {RestController.class}) //指定一个或多个注解,被这些注解所标记的 Controller 会被该 @ControllerAdvice 管理。
public class GlobalExceptionHandler { //全局异常处理
@ResponseBody
@ExceptionHandler(value = Exception.class)
public ResponseMessages<?> errorHandler(Exception e) {
return new ResponseMessages<>(10012, e.getMessage() + "exep-- 服务错误", false);
} }

全局数据绑定

全局数据绑定功能可以用来做一些初始化的数据操作,我们可以将一些公共的数据定义在添加了 @ControllerAdvice 注解的类中,这样,在每一个 Controller 的接口中,就都能够访问导致这些数据。

使用步骤,首先定义全局数据,如下:

@ControllerAdvice
public class MyGlobalExceptionHandler {
@ModelAttribute(name = "md")
public Map<String,Object> mydata() {
HashMap<String, Object> map = new HashMap<>();
map.put("age", 99);
map.put("gender", "男");
return map;
}
}

使用 @ModelAttribute 注解标记该方法的返回数据是一个全局数据,默认情况下,这个全局数据的 key 就是返回的变量名,value 就是方法返回值,当然开发者可以通过 @ModelAttribute 注解的 name 属性去重新指定 key。

定义完成后,在任何一个Controller 的接口中,都可以获取到这里定义的数据:

@RestController
public class HelloController {
@GetMapping("/hello")
public String hello(Model model) {
Map<String, Object> map = model.asMap();
System.out.println(map);
int i = 1 / 0;
return "hello controller advice";
}
}

全局数据预处理

考虑我有两个实体类,Book 和 Author,分别定义如下:

public class Book {
private String name;
private Long price;
//getter/setter
}
public class Author {
private String name;
private Integer age;
//getter/setter
}

此时,如果我定义一个数据添加接口,如下:

@PostMapping("/book")
public void addBook(Book book, Author author) {
System.out.println(book);
System.out.println(author);
}

这个时候,添加操作就会有问题,因为两个实体类都有一个 name 属性,从前端传递时 ,无法区分。此时,通过 @ControllerAdvice 的全局数据预处理可以解决这个问题

解决步骤如下:

1.给接口中的变量取别名

@PostMapping("/book")
public void addBook(@ModelAttribute("b") Book book, @ModelAttribute("a") Author author) {
System.out.println(book);
System.out.println(author);
}

2.进行请求数据预处理
在 @ControllerAdvice 标记的类中添加如下代码:

@InitBinder("b")
public void b(WebDataBinder binder) {
binder.setFieldDefaultPrefix("b.");
}
@InitBinder("a")
public void a(WebDataBinder binder) {
binder.setFieldDefaultPrefix("a.");
}

@InitBinder("b") 注解表示该方法用来处理和Book和相关的参数,在方法中,给参数添加一个 b 前缀,即请求参数要有b前缀.

3.发送请求

请求发送时,通过给不同对象的参数添加不同的前缀,可以实现参数的区分.

springboot项目全局异常处理@ControllerAdvice(方式二)的更多相关文章

  1. springmvc、 springboot 项目全局异常处理

    异常在项目中那是不可避免的,通常情况下,我们需要对全局异常进行处理,下面介绍两种比较常用的情况. 准备工作: 在捕获到异常的时候,我们通常需要返回给前端错误码,错误信息等,所以我们需要手动封装一个js ...

  2. Springboot项目统一异常处理

    Springboot项目统一异常处理 一.接口返回值封装 1. 定义Result对象,作为通用返回结果封装 2. 定义CodeMsg对象,作为通用状态码和消息封装 二.定义全局异常类 三.定义异常处理 ...

  3. springmvc全局异常处理ControllerAdvice区分返回响应类型是页面还是JSON

    思路: 加一个拦截器,在preHandler中取得HandlerMethod,判断其方法的返回类型,以及方法的注解和类的注解. 如果返回是json,收到异常则返回默认的异常包装类型. 如果返回是页面, ...

  4. 异常处理的方式二:throws+异常类型

    package com.yhqtv.demo01Exception; import java.io.File; import java.io.FileInputStream; import java. ...

  5. SpringBoot整合全局异常处理&SpringBoot整合定时任务Task&SpringBoot整合异步任务

    ============整合全局异常=========== 1.整合web访问的全局异常 如果不做全局异常处理直接访问如果报错,页面会报错500错误,对于界面的显示非常不友好,因此需要做处理. 全局异 ...

  6. 014-Spring Boot web【三】拦截器HandlerInterceptor、异常处理页面,全局异常处理ControllerAdvice

    一.拦截器HandlerInterceptor 1.1.HandlerInterceptor接口说明 preHandle,congtroller执行前,如果返回false请求终端 postHandle ...

  7. 【springboot】全局异常处理

    转自: https://blog.csdn.net/cp026la/article/details/86495196 前言: 开发中异常的处理必不可少,常用的就是 throw 和 try catch, ...

  8. springBoot的全局异常处理

    GlobalException.java package com.bank.util; import com.bank.exception.ContentEmpyException; import c ...

  9. Springboot项目全局异常统一处理

    转自https://blog.csdn.net/hao_kkkkk/article/details/80538955 最近在做项目时需要对异常进行全局统一处理,主要是一些分类入库以及记录日志等,因为项 ...

  10. (入门SpringBoot)SpringBoot项目数据源以及整合mybatis(二)

    1.配置tomcat数据源: #   数据源基本配置spring.datasource.url=jdbc:mysql://localhost:3306/shoptest?useUnicode=true ...

随机推荐

  1. docker启动完美容器的过程

    这里是我用docker启动所有常见的容器完美的过程,就是一次创建,后面就可以一直使用 文档: nanshaws/docker-everything: 用docker来创建各种容器,完美文档教你按照步骤 ...

  2. 解决This application failed to start because cannot find or load the qt platform plugin 'xcb'

    问题描述: 在使用linux系统训练自己的数据集合时,出现了上述问题,首先第一个想法就是先Google,但是在看了一些国内外的文章后依然没有将问题解决 问题原因: 这是由于这几天我在安装cuda.cu ...

  3. python、numpy计算不同文档下的词的TF-IDF值以及进行文档相似度匹配(实战)

    TF-IDF 计算公式(一个词的 tf-idf 值在不同文档,它的值也不同): 1.根据已有的原始数据,只展示了前5片文档,content是文档内容,s_words是通过jieba分词将文档划分成了若 ...

  4. tarjan无向图割点与割边板子

    \(\Huge{割点}\) \(无向图割点判定法则\) 当遍历到一个点x时,这个点为割点的情况有两种: 第一种是该节点为根节点且子节点数>=2,必导致两个子节点不连通: 第二种是该节点不为根节点 ...

  5. 制造业工厂生产管理MES系统中的设备管理模块

    制造业工厂万界星空科技生产管理MES系统中的设备管理模块介绍: 随时工厂数字化建设的大力推进,设备管理的效率得到了很大的提升,特别是作为机加工企业,设备是整个企业非常重要的核心资产. 1.MES设备管 ...

  6. pycharm设置Ctrl+鼠标滚轮放大缩小字体

    方式一: File --> setting --> Editor-->General,勾选. 方式二: 放大的设置 File --> setting --> Keymap ...

  7. 三个月我迁移了100PB数据

    2023年马上结束,这一年做了不少事情,有一项我可以吹好几年,忍不住和大家分享一下啊. 需求 去年底收到一项需求,要求2个月内从某云存储迁移100PB数据到微软云存储,包含几百亿个文件.当时听到这个数 ...

  8. APP性能测试-客户端性能测试

    https://blog.csdn.net/xiaomaoxiao336368/article/details/83547318

  9. Guava Cache 异步刷新技巧,你值得拥有!

    Guava Cache是一款非常优秀的本地缓存框架,提供简洁易用的 API 供开发者使用. 这篇文章,我们聊聊如何使用 Guava Cache 异步刷新技巧带飞系统性能 . 1 基本用法 首先,在 J ...

  10. Freezable ---探索WPF中Freezable承载数据的原理

    引言 在之前写的一篇文章[WPF --- 如何以Binding方式隐藏DataGrid列]中,我先探索了 DataGridTextColumn 为什么不在可视化树结构内?又给出了解决方案,使用 Fre ...