Spring之webMvc异常处理
异常处理可以前端处理,也可以后端处理。
从稳妥的角度出发,两边都应该进行处理。
本文专门阐述如何在服务端进行http请求异常处理。
一、常见的异常类型
当我们做http请求的时候,会有各种各样的可能错误,比较常见的例如:
1.服务类异常
2.接口异常,而接口异常有各种各样的情况
究极就是接口的异常。
异常可以发生在请求的各个步骤之中,这里主要阐述网络通讯正常的情况。
这些通讯异常在方法 org.springframework.web.servlet.mvc.support.DefaultHandlerExceptionResolver.doResolveException(HttpServletRequest, HttpServletResponse, Object, Exception)中
有详细的描述:
if (ex instanceof HttpRequestMethodNotSupportedException) {
return handleHttpRequestMethodNotSupported(
(HttpRequestMethodNotSupportedException) ex, request, response, handler);
}
else if (ex instanceof HttpMediaTypeNotSupportedException) {
return handleHttpMediaTypeNotSupported(
(HttpMediaTypeNotSupportedException) ex, request, response, handler);
}
else if (ex instanceof HttpMediaTypeNotAcceptableException) {
return handleHttpMediaTypeNotAcceptable(
(HttpMediaTypeNotAcceptableException) ex, request, response, handler);
}
else if (ex instanceof MissingPathVariableException) {
return handleMissingPathVariable(
(MissingPathVariableException) ex, request, response, handler);
}
else if (ex instanceof MissingServletRequestParameterException) {
return handleMissingServletRequestParameter(
(MissingServletRequestParameterException) ex, request, response, handler);
}
else if (ex instanceof ServletRequestBindingException) {
return handleServletRequestBindingException(
(ServletRequestBindingException) ex, request, response, handler);
}
else if (ex instanceof ConversionNotSupportedException) {
return handleConversionNotSupported(
(ConversionNotSupportedException) ex, request, response, handler);
}
else if (ex instanceof TypeMismatchException) {
return handleTypeMismatch(
(TypeMismatchException) ex, request, response, handler);
}
else if (ex instanceof HttpMessageNotReadableException) {
return handleHttpMessageNotReadable(
(HttpMessageNotReadableException) ex, request, response, handler);
}
else if (ex instanceof HttpMessageNotWritableException) {
return handleHttpMessageNotWritable(
(HttpMessageNotWritableException) ex, request, response, handler);
}
else if (ex instanceof MethodArgumentNotValidException) {
return handleMethodArgumentNotValidException(
(MethodArgumentNotValidException) ex, request, response, handler);
}
else if (ex instanceof MissingServletRequestPartException) {
return handleMissingServletRequestPartException(
(MissingServletRequestPartException) ex, request, response, handler);
}
else if (ex instanceof BindException) {
return handleBindException((BindException) ex, request, response, handler);
}
else if (ex instanceof NoHandlerFoundException) {
return handleNoHandlerFoundException(
(NoHandlerFoundException) ex, request, response, handler);
}
else if (ex instanceof AsyncRequestTimeoutException) {
return handleAsyncRequestTimeoutException(
(AsyncRequestTimeoutException) ex, request, response, handler);
}
我们整理为表格:
| 编码 | 名称 | 备注 |
| handleHttpRequestMethodNotSupported | 请求方法不支持 | 例如RequestMapping只指定了post,但用get请求 |
| HttpMediaTypeNotSupportedException | 媒体类型不支持 | 例如消息转换器可能只处理JSON,但请求头确设置为xml之类的 |
| HttpMediaTypeNotAcceptableException | 媒体类型不可接受 | 请求处理器无法生成客户端可以支持的响应内容 |
| MissingPathVariableException | 缺失路径变量 |
请求url缺乏路径变量。例如 @RequestMapping("/show/{name}") public Object show(@PathVariable String name){} 工程师可能少写了{name} |
| MissingServletRequestParameterException | 缺失Servlet请求参数 | 例如使用了@RequstParam,但是url并没有提供对应的参数 |
| ServletRequestBindingException | Servlet请求绑定异常 | 在执行绑定的时候发生的异常 |
| ConversionNotSupportedException | 不支持的转换异常 | 无法为bean找到匹配的编辑器或者转换器 |
| TypeMismatchException | 类型不匹配异常 | 给bean复制的时候,发现类型不匹配 |
| HttpMessageNotReadableException | http消息无法读取 | 当HttpMessageConverter#read方法发生错误的时候 |
| HttpMessageNotWritableException | http消息无法写异常 | 当HttpMessageConverter#write方法发生错误的时候 |
| MethodArgumentNotValidException | 方法参数不可用异常 | 验证 @Valid过的参数时候所发生的异常 |
| MissingServletRequestPartException | 缺失Servlet请求part异常 | 请求的媒体类型是文件类型(或者是附件),但内容没有 |
| BindException | 绑定异常 | |
| NoHandlerFoundException | 没有找到处理器 |
By default when the DispatcherServlet can't find a handler for a request it sends a 404 response. However if its property "throwExceptionIfNoHandlerFound" is set to 默认情况下,分发器处理器程序无法找到请求的处理器的时候(例如静态资源或者请求控制器方法的时候),会发送一个404响应。此外会设置属性throwExceptionIfNoHandlerFound=true,并引发没有处理器异常。用户可以考虑配置一个HandlerExceptionResolver来处理 |
| AsyncRequestTimeoutException | 异步请求超时异常。即503 错误。 |
spring和springboot中和异常/错误有关的类远不止上表那么多。
出于代码的严谨性要求,几乎所有的函数/过程都会有异常处理(try catch throw),限于篇幅,不会讨论所有的代码,也没有必要。
二、WMS中的异常配置
关于wms的介绍,可以参考: wms配置简介
wms可以处理异常的地方有几个,但我们专门考虑exception字眼的部分。
@Bean
public HandlerExceptionResolver handlerExceptionResolver(
@Qualifier("mvcContentNegotiationManager") ContentNegotiationManager contentNegotiationManager) {
List<HandlerExceptionResolver> exceptionResolvers = new ArrayList<>();
configureHandlerExceptionResolvers(exceptionResolvers);
if (exceptionResolvers.isEmpty()) {
addDefaultHandlerExceptionResolvers(exceptionResolvers, contentNegotiationManager);
}
extendHandlerExceptionResolvers(exceptionResolvers);
HandlerExceptionResolverComposite composite = new HandlerExceptionResolverComposite();
composite.setOrder(0);
composite.setExceptionResolvers(exceptionResolvers);
return composite;
} /**
* Override this method to configure the list of
* {@link HandlerExceptionResolver HandlerExceptionResolvers} to use.
* <p>Adding resolvers to the list turns off the default resolvers that would otherwise
* be registered by default. Also see {@link #addDefaultHandlerExceptionResolvers}
* that can be used to add the default exception resolvers.
* @param exceptionResolvers a list to add exception resolvers to (initially an empty list)
*/
protected void configureHandlerExceptionResolvers(List<HandlerExceptionResolver> exceptionResolvers) {
} /**
* A method available to subclasses for adding default
* {@link HandlerExceptionResolver HandlerExceptionResolvers}.
* <p>Adds the following exception resolvers:
* <ul>
* <li>{@link ExceptionHandlerExceptionResolver} for handling exceptions through
* {@link org.springframework.web.bind.annotation.ExceptionHandler} methods.
* <li>{@link ResponseStatusExceptionResolver} for exceptions annotated with
* {@link org.springframework.web.bind.annotation.ResponseStatus}.
* <li>{@link DefaultHandlerExceptionResolver} for resolving known Spring exception types
* </ul>
*/
protected final void addDefaultHandlerExceptionResolvers(List<HandlerExceptionResolver> exceptionResolvers,
ContentNegotiationManager mvcContentNegotiationManager) { ExceptionHandlerExceptionResolver exceptionHandlerResolver = createExceptionHandlerExceptionResolver();
exceptionHandlerResolver.setContentNegotiationManager(mvcContentNegotiationManager);
exceptionHandlerResolver.setMessageConverters(getMessageConverters());
exceptionHandlerResolver.setCustomArgumentResolvers(getArgumentResolvers());
exceptionHandlerResolver.setCustomReturnValueHandlers(getReturnValueHandlers());
if (jackson2Present) {
exceptionHandlerResolver.setResponseBodyAdvice(
Collections.singletonList(new JsonViewResponseBodyAdvice()));
}
if (this.applicationContext != null) {
exceptionHandlerResolver.setApplicationContext(this.applicationContext);
}
exceptionHandlerResolver.afterPropertiesSet();
exceptionResolvers.add(exceptionHandlerResolver); ResponseStatusExceptionResolver responseStatusResolver = new ResponseStatusExceptionResolver();
responseStatusResolver.setMessageSource(this.applicationContext);
exceptionResolvers.add(responseStatusResolver); exceptionResolvers.add(new DefaultHandlerExceptionResolver());
}
通过wms机制,可以覆盖bean(handlerExceptionResolver),或者覆盖方法 configureHandlerExceptionResolvers添加异常处理解析器。
不过一般情况下,我们都没有那个必要。
一般情况下,使用DefaultHandlerExceptionResolver进行处理即可,即前文介绍的内容。
三、springboot的http请求异常
如果使用springboot开发,那么springboot会通过自动配置引入一个 org.springframework.boot.autoconfigure.web.servlet.error.BasicErrorController
这类控制器类实现了接口 org.springframework.boot.web.servlet.error.ErrorController。
根据springboot的有关描述,我们可以实现它接口org.springframework.boot.web.servlet.error.ErrorController,以便覆盖默认的实现。
例如:
@Controller
public class ErrController implements ErrorController { @RequestMapping("/error")
public String handleError(HttpServletRequest request,HttpServletResponse response) {
int statusCode=response.getStatus();
if (statusCode == 404) {
return "/main/err.html";
}
else if (statusCode == 444) {
return "/main/login.html";
}
return "";
}
}
需要注意的是,ErrorController 的代码是在wms的异常处理之后执行的。
此外,也可以只用控制器advice注解处理, 例如:SpringBoot系列——自定义统一异常处理 - huanzi-qch - 博客园 (cnblogs.com)
四、小结
spring为了少让我们的代码出现问题,还引入了一个机制:验证。例如可以验证参数验证。不过验证仅仅只是解决了少数的异常情形,虽然参数不合法的发生的数量还是比较多的。
但这个验证一般情况下,也不需要,因为一般在客户端就先处理了!
Spring之webMvc异常处理的更多相关文章
- spring mvc4:异常处理
前面学习过struts2的异常处理,今天来看下spring mvc4的异常处理: 一.Servlet配置文件修改 <bean id="exceptionResolver" c ...
- 使用Spring MVC统一异常处理实战
1 描述 在J2EE项目的开发中,不管是对底层的数据库操作过程,还是业务层的处理过程,还是控制层的处理过程,都不可避免会遇到各种可预知的.不可预知的异常需要处理.每个过程都单独处理异常,系统的代码耦合 ...
- Spring MVC 统一异常处理
Spring MVC 统一异常处理 看到 Exception 这个单词都心慌 如果有一天你发现好久没有看到Exception这个单词了,那你会不会想念她?我是不会的.她如女孩一样的令人心动又心慌,又或 ...
- 【Spring学习笔记-MVC-15.1】Spring MVC之异常处理=404界面
作者:ssslinppp 异常处理请参考前篇博客:<[Spring学习笔记-MVC-15]Spring MVC之异常处理>http://www.cnblogs.com/sssl ...
- 使用Spring MVC统一异常处理实战<转>
1 描述 在J2EE项目的开发中,不管是对底层的数据库操作过程,还是业务层的处理过程,还是控制层的处理过程,都不可避免会遇到各种可预知的.不可预知的异常需要处理.每个过程都单独处理异常,系统的代码耦合 ...
- Spring 中的异常处理
工作中遇到这样的同事,问他活干完吗,他说开发好了,结果测试时发现各种异常情况未处理,联调测试时各种未知错误,最后联调完成比他预期的两倍工作量还多.这样的开发如果是新人还可以原谅,如果有工作经验且出现多 ...
- 编程小白入门分享三:Spring AOP统一异常处理
Spring AOP统一异常处理 简介 在Controller层,Service层,可能会有很多的try catch代码块.这将会严重影响代码的可读性."美观性".怎样才可以把更多 ...
- Spring Boot全局异常处理
本文为大家分享了Spring Boot全局异常处理,供大家参考,具体内容如下 1.后台处理异常 a.引入thymeleaf依赖 <!-- thymeleaf模板插件 --> <dep ...
- Spring MVC 全局异常处理&文件上传
Spring MVC 全局异常处理 使用SimpleMappingExceptionResolver实现异常处理 在welcome-servlet.xml进行如下配置: <bean class= ...
- 使用Spring MVC统一异常处理实战(转载)
原文地址:http://blog.csdn.net/ufo2910628/article/details/40399539 种方式: (1)使用Spring MVC提供的简单异常处理器SimpleMa ...
随机推荐
- WPF 基础 2D 图形学知识 判断点是否在线段上
在知道一个使用两个点表示的线段,和另一个点,求另一个点是否在线段上 本文算法属于通用的算法,可以在 WPF 和 UWP 和 Xamarin 等上运行,基本上所有的 .NET 平台都能执行 如下图,如果 ...
- redis系列02---缓存过期、穿透、击穿、雪崩
一.缓存过期 问题产生的原由: 内存空间有限,给缓存设置过期时间,但有些键值运气比较好,每次都没有被我的随机算法选中,每次都能幸免于难,这可不行,这些长时间过期的数据一直霸占着不少的内存空间! 解决方 ...
- STM32定时器原理
一.简介 不同的芯片定时器的数量不同,STM32F10x中一共有11个定时器,其中2个高级控制定时器,4个普通定时器和2个基本定时器,以及2个看门狗定时器和1个系统嘀嗒定时器. 基本定时器:TIM6. ...
- 程序是怎样跑起来的_第一章-对程序员来说CPU是什么
通过对第一章的学习,我了解了大体上CPU可以说是电脑的"大脑",即中央处理器.从功能来看可以分为寄存器,控制器,运算器和时钟.在这四个部分中,寄存器是最值得程序员注意的.总的来说, ...
- linux-centos7.6 硬盘挂载
目录 一 .功能 二.VM中设置硬盘 2.1 系统关机状态下 2.2 添加硬盘 三.系统中挂载硬盘 3.1 查看硬盘信息 3.2 硬盘分区 3.3 格式化硬盘 3.4 临时挂载硬盘 3.4 开机自动挂 ...
- Oracle删除列操作:逻辑删除和物理删除
概念 逻辑删除:逻辑删除并不是真正的删除,而是将表中列所对应的状态字段(status)做修改操作,实际上并未删除目标列数据或恢复这些列占用的磁盘空间.比如0是未删除,1是删除.在逻辑上数据是被删除了, ...
- synchronized原理-字节码分析、对象内存结构、锁升级过程、Monitor
本文分析的问题: synchronized 字节码文件分析之 monitorenter.monitorexit 指令 为什么任何一个Java对象都可以成为一把锁? 对象的内存结构 锁升级过程 Moni ...
- win11如何调解屏幕亮度【win10刚刚升级win11】?
打开电脑后鼠标右键,点击个性化 点击系统 点击屏幕亮度 滑动按钮,调解屏幕亮度即可
- Vue cli介绍
Vue CLI 是一个基于 Vue.js 进行快速开发的完整系统,提供: 通过 @vue/cli 实现的交互式的项目脚手架. 通过 @vue/cli + @vue/cli-service-global ...
- Sublime快速在当前目录下新建文件(advanceNewfile插件)
1.ctrl+shift+p,输入pci,选择第一个,回车 2.输入 advanceNewfile 安装 3.ctrl+alt+n 新建文件自动保存在当前目录下