@ControllerAdvice 全局异常处理
使用@ControllerAdvice 定义 全局异常处理
package com.app; import java.io.IOException;
import java.io.PrintWriter; import javax.servlet.http.HttpServletResponse; import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.multipart.MaxUploadSizeExceededException; /**
* ContorllerAdvice 最常见的使用场景是全局异常处理
* 一般搭配 @ExceptionHandler @ModelAttribute 以及 @InitBinder 使用
* 如下是, 当单个文件超出最大size时 对应的自定义处理方法
*
* <p>By default the methods in an {@code @ControllerAdvice} apply globally to
* all Controllers.
*
* spring:
servlet:
multipart:
max-file-size: 50KB
*
*/
@ControllerAdvice
public class CustomExceptionHandler { @ExceptionHandler(MaxUploadSizeExceededException.class)
public void uploadException(MaxUploadSizeExceededException e, HttpServletResponse resp) throws IOException {
resp.setContentType("text/html;charset=utf-8");
PrintWriter out = resp.getWriter();
out.write("文件大小超出限制!");
out.flush();
out.close();
}
}
当需要将自定义结果写入Response时,有更好的选择:ResponseEntityExceptionHandler( 作为 @ControllerAdvice的基类)
Open Declaration org.springframework.web.servlet.mvc.method.annotation.ResponseEntityExceptionHandler A convenient base class for @ControllerAdvice classes that wish to provide centralized exception handling across all @RequestMapping methods through @ExceptionHandler methods. This base class provides an @ExceptionHandler method for handling internal Spring MVC exceptions. This method returns a ResponseEntity for writing to the response with a message converter, in contrast to DefaultHandlerExceptionResolver which returns a ModelAndView. If there is no need to write error content to the response body, or when using view resolution (e.g., via ContentNegotiatingViewResolver), then DefaultHandlerExceptionResolver is good enough.
如下,在Service中抛出 Exception
package com.app.service;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service; import com.app.dao.CityRepository;
import com.app.exceptions.CityNotFoundException;
import com.app.exceptions.NoDataFoundException;
import com.app.model.City; import java.util.List; @Service
public class CityService implements ICityService { @Autowired
private CityRepository cityRepository; @Override
public City findById(Long id) { return cityRepository.findById(id)
.orElseThrow(() -> new CityNotFoundException(id));
} @Override
public City save(City city) { return cityRepository.save(city);
} @Override
public List<City> findAll() { List<City> cities = (List<City>) cityRepository.findAll(); if (cities.isEmpty()) { throw new NoDataFoundException();
} return cities;
} }
并使用ControllerAdvice 标注的类做全局处理:(使用ResponseEntity 返回定制信息以及HttpStatus Code)
package com.app.exceptions;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.MethodArgumentNotValidException;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.context.request.WebRequest;
import org.springframework.web.servlet.mvc.method.annotation.ResponseEntityExceptionHandler; import java.time.LocalDate;
import java.time.LocalDateTime;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors; @ControllerAdvice
public class ControllerAdvisor extends ResponseEntityExceptionHandler { @ExceptionHandler(CityNotFoundException.class)
public ResponseEntity<Object> handleCityNotFoundException(
CityNotFoundException ex, WebRequest request) { Map<String, Object> body = new LinkedHashMap<>();
body.put("timestamp", LocalDateTime.now());
body.put("message", "City not found"); return new ResponseEntity<>(body, HttpStatus.NOT_FOUND);
} @ExceptionHandler(NoDataFoundException.class)
public ResponseEntity<Object> handleNodataFoundException(
NoDataFoundException ex, WebRequest request) { Map<String, Object> body = new LinkedHashMap<>();
body.put("timestamp", LocalDateTime.now());
body.put("message", "No cities data found"); return new ResponseEntity<>(body, HttpStatus.NOT_FOUND);
} @Override
protected ResponseEntity<Object> handleMethodArgumentNotValid(
MethodArgumentNotValidException ex, HttpHeaders headers,
HttpStatus status, WebRequest request) { Map<String, Object> body = new LinkedHashMap<>();
body.put("timestamp", LocalDate.now());
body.put("status", status.value()); List<String> errors = ex.getBindingResult()
.getFieldErrors()
.stream()
.map(x -> x.getField() + x.getDefaultMessage())
.collect(Collectors.toList()); body.put("errors", errors); return new ResponseEntity<>(body, HttpStatus.BAD_REQUEST);
}
}
准备测试数据方法1:
使用MyRunner
package com.app;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.CommandLineRunner;
import org.springframework.stereotype.Component; import com.app.dao.CityRepository;
import com.app.model.City; @Component
public class MyRunner implements CommandLineRunner { private static final Logger logger = LoggerFactory.getLogger(MyRunner.class); @Autowired
private CityRepository cityRepository; @Override
public void run(String... args) throws Exception { logger.info("Saving cities"); cityRepository.save(new City("Bratislava", 432000));
cityRepository.save(new City("Budapest", 1759000));
cityRepository.save(new City("Prague", 1280000));
cityRepository.save(new City("Warsaw", 1748000));
cityRepository.save(new City("Los Angeles", 3971000));
cityRepository.save(new City("New York", 8550000));
cityRepository.save(new City("Edinburgh", 464000));
cityRepository.save(new City("Suzhou", 4327066));
cityRepository.save(new City("Zhengzhou", 4122087));
cityRepository.save(new City("Berlin", 3671000));
}
}
MyRunner 类会在项目启动之后执行:
准备测试数据方法2:
在src/main/resource 下 create 一个 data.sql ,如下:
INSERT INTO cities(name, population) values('Hello',100);
INSERT INTO cities(name, population) values('World',200);
发生异常时的返回值:
Reference:http://zetcode.com/springboot/controlleradvice/
Code: https://github.com/XLuffyStory/SpringBootStudy/tree/master/springboot-controlleradvice
@ControllerAdvice 全局异常处理的更多相关文章
- @ControllerAdvice全局异常处理不起作用原因及解决办法
这段时间使用springboot搭建基础框架,作为springboot新手,各种问题都有. 当把前端框架搭建进来时,针对所有controller层的请求,所发生的异常,需要有一个统一的异常处理,然后返 ...
- 014-Spring Boot web【三】拦截器HandlerInterceptor、异常处理页面,全局异常处理ControllerAdvice
一.拦截器HandlerInterceptor 1.1.HandlerInterceptor接口说明 preHandle,congtroller执行前,如果返回false请求终端 postHandle ...
- Spring中通过java的@Valid注解和@ControllerAdvice实现全局异常处理。
通过java原生的@Valid注解和spring的@ControllerAdvice和@ExceptionHandler实现全局异常处理的方法: controller中加入@Valid注解: @Req ...
- springmvc全局异常处理ControllerAdvice区分返回响应类型是页面还是JSON
思路: 加一个拦截器,在preHandler中取得HandlerMethod,判断其方法的返回类型,以及方法的注解和类的注解. 如果返回是json,收到异常则返回默认的异常包装类型. 如果返回是页面, ...
- 《Spring全局异常处理》从零掌握@ControllerAdvice注解
一.开门见山 在前后端分离框架的大趋势下,前后端基本的职责已经确定. 前端主要负责界面的处理以及基本的判空检验.数据来源则通过vue调用后端发布的接口. 后端的原型还是mvc的模式: controll ...
- Spring Boot 全局异常处理
Spring Boot版本 1.5 @ControllerAdvice public class GlobalExceptionHandler extends ResponseEntityExcept ...
- SpringBoot整合全局异常处理&SpringBoot整合定时任务Task&SpringBoot整合异步任务
============整合全局异常=========== 1.整合web访问的全局异常 如果不做全局异常处理直接访问如果报错,页面会报错500错误,对于界面的显示非常不友好,因此需要做处理. 全局异 ...
- Spring 全局异常处理
[参考文章]:Spring全局异常处理的三种方式 [参考文章]:Spring Boot 系列(八)@ControllerAdvice 拦截异常并统一处理 [参考文章]:@ControllerAdvic ...
- springBoot注解大全JPA注解springMVC相关注解全局异常处理
https://www.cnblogs.com/tanwei81/p/6814022.html 一.注解(annotations)列表 @SpringBootApplication:包含了@Compo ...
随机推荐
- Spring防止Xss配置
web.xml配置 <!-- xss过滤器 --> <filter> <filter-name>XssFilter</filter-name> < ...
- Java加密数据库
一.背景 数据库配置以明文方式展示如图,会造成安全隐患,如果有黑客入侵会造成密码泄露,信息窃取和破坏等. 二.加密步骤 1.对数据库信息加密: 对数据库中的账号和密码信息进行加密(选择一种算法)然后替 ...
- sql server truncate语句
truncate语句 --truncate table '表名' --这样就利用SQL语句清空了该数据表,而不保留日志
- 基于EPICS实现西门子S7通信
(1) EPICS官网下载Demo并复制文件到指定位置 (2) 创建Modules文件夹,wget https://epics.anl.gov/download/modules ...
- 多列表zip合并的csv持久化储存
有时xpath爬取数据之后会返回多个列表,这些列表的长度一样,这时候可以用zip()合并,然后返回一个zip对象,直接传入储存函数,进行持久化储存 例如: name=['张三','李四','王五'] ...
- O023、理解Nova架构
参考https://www.cnblogs.com/CloudMan6/p/5410447.html Compute Service Nova 是OpenStack最核心的服务,负责维护和管理云环 ...
- SQL这样干,你就是给自己刨坑.....
SQL是作为一个程序员接触得非常多的一种语言,但是,很多时候,我们会发现,有些SQL的执行效率异常的差,造成了数据库的负担.我们通过分析这些有问题的SQL,就可以发现很多我们平时在写SQL的时候忽略的 ...
- 关于redis的几件小事(十)redis cluster模式
redis cluster是redis提供的集群模式. 1.redis cluster的架构 ①可以有多个master node,每个master node 都可以挂载多个slave node. ②读 ...
- 关于redis的几件小事(九)redis的并发竞争问题
1.什么是并发竞争 就是多客户端同时并发写一个key,可能本来应该先到的数据后到了,导致数据版本错了.或者是多客户端同时获取一个key,修改值之后再写回去,只要顺序错了,数据就错了. 2.怎么解决 采 ...
- Swift(一)语言介绍
Swift是苹果2014年推出的全新的编程语言,它继承了C语言.ObjC的特性,且克服了C语言的兼容性问题. Swift发展过程中不仅保留了ObjC很多语法特性,它也借鉴了多种现代化语言的特点,在其中 ...