异常处理可以前端处理,也可以后端处理。

从稳妥的角度出发,两边都应该进行处理。

本文专门阐述如何在服务端进行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 true this exception is raised and may be handled with a configured HandlerExceptionResolver.

默认情况下,分发器处理器程序无法找到请求的处理器的时候(例如静态资源或者请求控制器方法的时候),会发送一个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异常处理的更多相关文章

  1. spring mvc4:异常处理

    前面学习过struts2的异常处理,今天来看下spring mvc4的异常处理: 一.Servlet配置文件修改 <bean id="exceptionResolver" c ...

  2. 使用Spring MVC统一异常处理实战

    1 描述 在J2EE项目的开发中,不管是对底层的数据库操作过程,还是业务层的处理过程,还是控制层的处理过程,都不可避免会遇到各种可预知的.不可预知的异常需要处理.每个过程都单独处理异常,系统的代码耦合 ...

  3. Spring MVC 统一异常处理

    Spring MVC 统一异常处理 看到 Exception 这个单词都心慌 如果有一天你发现好久没有看到Exception这个单词了,那你会不会想念她?我是不会的.她如女孩一样的令人心动又心慌,又或 ...

  4. 【Spring学习笔记-MVC-15.1】Spring MVC之异常处理=404界面

    作者:ssslinppp       异常处理请参考前篇博客:<[Spring学习笔记-MVC-15]Spring MVC之异常处理>http://www.cnblogs.com/sssl ...

  5. 使用Spring MVC统一异常处理实战<转>

    1 描述 在J2EE项目的开发中,不管是对底层的数据库操作过程,还是业务层的处理过程,还是控制层的处理过程,都不可避免会遇到各种可预知的.不可预知的异常需要处理.每个过程都单独处理异常,系统的代码耦合 ...

  6. Spring 中的异常处理

    工作中遇到这样的同事,问他活干完吗,他说开发好了,结果测试时发现各种异常情况未处理,联调测试时各种未知错误,最后联调完成比他预期的两倍工作量还多.这样的开发如果是新人还可以原谅,如果有工作经验且出现多 ...

  7. 编程小白入门分享三:Spring AOP统一异常处理

    Spring AOP统一异常处理 简介 在Controller层,Service层,可能会有很多的try catch代码块.这将会严重影响代码的可读性."美观性".怎样才可以把更多 ...

  8. Spring Boot全局异常处理

    本文为大家分享了Spring Boot全局异常处理,供大家参考,具体内容如下 1.后台处理异常 a.引入thymeleaf依赖 <!-- thymeleaf模板插件 --> <dep ...

  9. Spring MVC 全局异常处理&文件上传

    Spring MVC 全局异常处理 使用SimpleMappingExceptionResolver实现异常处理 在welcome-servlet.xml进行如下配置: <bean class= ...

  10. 使用Spring MVC统一异常处理实战(转载)

    原文地址:http://blog.csdn.net/ufo2910628/article/details/40399539 种方式: (1)使用Spring MVC提供的简单异常处理器SimpleMa ...

随机推荐

  1. WPF 已知问题 dotnet 6 设置 InvariantGlobalization 之后将丢失默认绑定转换导致 XAML 抛出异常

    在设置了 InvariantGlobalization 为 true 之后,将会发现原本能正常工作的 XAML 可能就会抛出异常.本文将告诉大家此问题的原因 这是有开发者在 WPF 仓库上给我报告的 ...

  2. K8s控制器---Statefulset(11)

    一.Statefulset概述 1.1 Statefulset控制器:概念和原理解读 StatefulSet 是为了管理有状态服务的问题而设计的 扩展: 有状态服务? StatefulSet 是有状态 ...

  3. vue-hbuilder打包-调取摄像头或上传图片

    方法一: <input type="file" accept="image/*" capture="camera" > 方法二: ...

  4. 【爬虫案例】用Python爬取抖音热榜数据!

    目录 一.爬取目标 二.编写爬虫代码 三.同步讲解视频 3.1 代码演示视频 四.获取完整源码 一.爬取目标 您好,我是@马哥python说,一名10年程序猿. 本次爬取的目标是:抖音热榜 共爬取到5 ...

  5. 微服务 - 作业调度 · Hangfire集成式 · 仪表盘 · DolphinScheduler分布式 · 定义流程

    系列目录 微服务 - 1.概念 · 应用 · 架构 · 通讯 · 授权 · 跨域 · 限流 微服务 - 2.IdentityServer4认证授权 · 概念认识 · 运行过程 · 实践应用 微服务 - ...

  6. gin里获取http请求过来的参数

    https://www.bilibili.com/video/av68769981/?p=2 课程代码: https://www.qfgolang.com/?special=ginkuangjia&a ...

  7. 2020版IDEA配置Tomcat 10出现卡主问题

    问题描述 配置了2020版的IDE和Tomcat,但是产生了,日志打印中途,卡住了的问题,如图: 18-Aug-2021 00:46:09.763 信息 [main] org.apache.catal ...

  8. 在 ThinkPad E470 上安装 Ubuntu 16.04 无线网卡驱动

    目录 文章目录 目录 安装 安装 # 查看无线网卡驱动类型,E470 一般为 RTL8821CE lspci # 安装必要工具 sudo apt-get install build-essential ...

  9. Python基础篇(流程控制)

    流程控制是程序运行的基础,流程控制决定了程序按照什么样的方式执行. 条件语句 条件语句一般用来判断给定的条件是否成立,根据结果来执行不同的代码,也就是说,有了条件语句,才可以根据不同的情况做不同的事, ...

  10. npm创建项目

    创建项目 创建项目目录 首先新建一个文件夹,这里存放着我们的项目. 创建项目文件 这里不使用任何项目模板,相当于使用空模板. 进入这个文件夹,再cmd中运行npm init. 然后按照提示输入pack ...