Spring 3.2的REST异常处理

1.概述

本文将重点介绍如何使用REST API的Spring实现异常处理 。 我们将介绍在Spring 3.2之前可用的较旧的解决方案,然后是对Spring 3.2的新支持。

本文的主要目的是展示如何最好地将应用程序中的异常映射到HTTP状态代码。 哪种状态代码不适合本文中的哪种情况,REST错误表示的语法也不属于本文的范围。

在Spring 3.2之前,在Spring MVC应用程序中处理异常的两种主要方法是: HandlerExceptionResolver@ExceptionHandler批注。 Spring 3.2引入了新的@ControllerAdvice注释,以解决前两种解决方案的局限性。

所有这些确实有一个共同点–它们很好地处理了关注点分离 :标准应用程序代码可以正常抛出异常以指示某种类型的失败–然后可以通过以下任意方式处理异常。

2.通过控制器级别

定义带有@ExceptionHandler注释的Controller级别方法非常容易:

public class FooController{...@ExceptionHandler({ CustomException1.class, CustomException2.class })public void handleException() {//}
}

一切都很好,但是这种方法确实有一个主要缺点–带@ExceptionHandler注释的方法仅对特定Controller有效 ,而不对整个应用程序全局有效。 当然,这使其不适用于通用异常处理机制。

一个常见的解决方案是让应用程序中的所有Controller都扩展Base Controller类 -但是,对于由于某种原因无法使Controllers扩展为此类的应用程序来说,这可能是个问题。 例如,控制器可能已经从另一个基类扩展了,该基类可能在另一个jar中,或者不能直接修改,或者它们本身也不能直接修改。

接下来,我们将讨论另一种解决异常处理问题的方法-一种全局的方法,不包括对现有工件(如Controllers)的任何更改。

3.通过

为了在REST API中实现统一的异常处理机制 ,我们需要使用HandlerExceptionResolver-这将解决应用程序在运行时抛出的所有异常。 在寻求自定义解析器之前,让我们看一下现有的实现。

3.1。 ExceptionHandlerExceptionResolver

该解析器是在Spring 3.1中引入的,默认情况下已在DispatcherServlet中启用。 这实际上是前面介绍的@ ExceptionHandler机制如何工作的核心组件。

3.2。 DefaultHandlerExceptionResolver

该解析器是在Spring 3.0中引入的,默认情况下已在DispatcherServlet中启用。 它用于将标准Spring异常解析为其对应的HTTP状态代码,即客户端错误– 4xx和服务器错误– 5xx状态代码。 这是它处理的Spring Exception 的完整列表 ,以及如何将它们映射到状态代码。

尽管它确实正确设置了响应的状态码,但此解析器的一个局限性在于它没有对响应的主体设置任何内容。 但是,在REST API的上下文中,状态代码确实不足以向客户端提供信息-响应也必须具有正文,以允许应用程序提供有关失败原因的其他信息。

这可以通过配置View分辨率和通过ModelAndView渲染错误内容来解决,但是解决方案显然不是最优的-这就是为什么Spring 3.2提供了更好的选择的原因-我们将在本文的后半部分讨论。

3.3。 ResponseStatusExceptionResolver

该解析器也在Spring 3.0中引入,默认情况下在DispatcherServlet中启用。 它的主要职责是使用自定义异常上可用的@ResponseStatus批注,并将这些异常映射到HTTP状态代码。

这样的自定义异常可能看起来像:

@ResponseStatus(value = HttpStatus.NOT_FOUND)
public final class ResourceNotFoundException extends RuntimeException {public ResourceNotFoundException() {super();}public ResourceNotFoundException(String message, Throwable cause) {super(message, cause);}public ResourceNotFoundException(String message) {super(message);}public ResourceNotFoundException(Throwable cause) {super(cause);}
}

DefaultHandlerExceptionResolver一样 ,此解析器在处理响应主体方面也受到限制 -它确实将状态代码映射到响应上,但主体仍为null。

3.4。 SimpleMappingExceptionResolverAnnotationMethodHandlerExceptionResolver

SimpleMappingExceptionResolver已经存在了很长时间–它来自较早的Spring MVC模型,并且与REST Service无关 。 它用于将异常类名称映射到视图名称。

Spring 3.0中引入了AnnotationMethodHandlerExceptionResolver来通过@ExceptionHandler批注处理异常,但是从Spring 3.2开始, ExceptionHandlerExceptionResolver弃用该方法。

3.5。 自定义HandlerExceptionResolver

DefaultHandlerExceptionResolverResponseStatusExceptionResolver的组合在为Spring RESTful Service提供良好的错误处理机制方面有很长的路要走-但主要的限制-无法控制响应的主体-证明创建新的异常解析器是合理的。

因此,新解析器的一个目标是启用一个信息量更大的响应主体,该主体也应符合客户端请求的表示类型(由Accept标头指定):

@Component
public class RestResponseStatusExceptionResolver extends AbstractHandlerExceptionResolver {@Overrideprotected ModelAndView doResolveException(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) {try {if (ex instanceof IllegalArgumentException) {return handleIllegalArgument((IllegalArgumentException) ex, response, handler);}...} catch (Exception handlerException) {logger.warn("Handling of [" + ex.getClass().getName() + "] resulted in Exception", handlerException);}return null;}private ModelAndView handleIllegalArgument(IllegalArgumentException ex, HttpServletResponse response) throws IOException {response.sendError(HttpServletResponse.SC_CONFLICT);String accept = request.getHeader(HttpHeaders.ACCEPT);...return new ModelAndView();}
}

这里需要注意的一个细节是请求本身是可用的,因此应用程序可以考虑客户端发送的Accept标头的值。 例如,如果客户端要求输入application / json,则在出现错误情况时,应用程序仍应返回以application / json编码的响应正文。

另一个重要的实现细节是返回ModelAndView -这是响应主体,它将允许应用程序对其进行必要的设置。

这种方法是用于Spring REST服务的错误处理的一致且易于配置的机制。 但是它确实有局限性 :它与低级HtttpServletResponse交互,并且适合使用ModelAndView的旧MVC模型-因此仍有改进的空间。

4.通过新的

Spring 3.2通过新的@ControllerAdvice批注支持全局@ExceptionHandler 。 这将启用一种机制,该机制有别于旧的MVC模型,并利用ResponseEntity以及@ExceptionHandler的类型安全性和灵活性:

@ControllerAdvice
public class RestResponseEntityExceptionHandler extends ResponseEntityExceptionHandler {@ExceptionHandler(value = { IllegalArgumentException.class, IllegalStateException.class })protected ResponseEntity<Object> handleConflict(RuntimeException ex, WebRequest request) {String bodyOfResponse = "This should be application specific";return handleExceptionInternal(ex, bodyOfResponse, new HttpHeaders(), HttpStatus.CONFLICT, request);}
}

新的批注允许将之前分散的多个@ExceptionHandler合并到单个全局错误处理组件中

实际的机制非常简单,但也非常灵活:

  • 它允许完全控制响应的主体以及状态代码
  • 它允许将多个异常映射到同一方法,以便一起处理
  • 它充分利用了更新的RESTful ResposeEntity响应

5.结论

本教程讨论了几种在Spring中为REST API实现异常处理机制的方法,从较旧的机制开始,一直到对Spring 3.2的新支持。 要在现实世界的REST服务中完整实现这些异常处理机制,请查看github项目 。

参考:来自badung博客的JCG合作伙伴 Eugen Paraschiv 提供的Spring 3 REST错误处理 。

翻译自: https://www.javacodegeeks.com/2013/02/exception-handling-for-rest-with-spring-3-2.html

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/369129.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

kali中常用的ctf工具

exiftool:查看图片的exif信息。 pngcheck:修复被破坏的png图片 pngtools:深入研究png文件的数据 steganographic&#xff1a;用来提取图片中的隐藏信息 stegsolve.jar:kali中没有该工具&#xff0c;但是可以自己下 gimp:提供了转换各类图像文件可视化数据的功能&#xff0c;还可…

linux将所有文件生成lst_Linux自定义repo文件

repo文件简介repo文件是CentOS中yum源(软件仓库)的配置文件&#xff0c;通常一个repo文件定义了一个或者多个软件仓库的细节内容&#xff0c;例如我们将从哪里下载需要安装或者升级的软件包&#xff0c;repo文件中的设置内容将被yum读取和应用yum原理YUM的工作原理并不复杂&…

使用JUnit规则测试预期的异常

这篇文章展示了如何使用JUnit测试预期的异常。 让我们从我们要测试的以下类开始&#xff1a; public class Person {private final String name;private final int age;/*** Creates a person with the specified name and age.** param name the name* param age the age* th…

CSS盒子模型之详解

前言&#xff1a; 盒子模型是css中最核心的基础知识&#xff0c;理解了这个重要的概念才能更好的排版&#xff0c;进行页面布局。一、css盒子模型概念 CSS盒子模型 又称框模型 (Box Model) &#xff0c;包含了元素内容&#xff08;content&#xff09;、内边距&#…

LeetCode的二分查找的练习部分总结

这两天由于工作的原因&#xff0c;一直没有写博客&#xff0c;但是却把LeetCode上面的题目做了不少——二分查找。上面这些题都是这两天写的。现在简单做一个总结。 首先二分查找的思想就是对一个有规律的元素&#xff08;事情&#xff09;进行不断的排除&#xff0c;最后找到符…

在Mac上安装IntelliJ IDEA

在Mac上安装IntelliJ IDEA http://www.jetbrains.com/idea/documentation/ 入门视频 这篇文章旨在介绍如何在Mac系统上安装IntelliJ IDEA&#xff0c;至于IntelliJ IDEA的介绍和使用方法&#xff0c;大家另行查阅&#xff0c;本篇的文章不再详细阐述。 简短解说&#xff0c;I…

mysql sohu_【MySQL中间件之SOHU-DBProxy】

SOHU-DBProxy是由 搜狐 数据库团队开发维护的一个基于MySQL协议的数据中间层项目。它在MySQL官方推出的MySQL-Proxy 0.8.3版本的基础上&#xff0c; 修改了大量bug&#xff0c;添加了很多功能特性。现在已经在sohu的多个业务线上使用DBProxy 兼容 MySQL 协议&#xff0c;可以用…

JavaFX:太空侵略者在175 LOC以下

使用当前版本的API&#xff0c;我对太空侵略者的评价不到175个LOC。 我的API中有很多“功能接口”&#xff0c;可以使用JavaFX 8&#xff08;例如SpriteProvider和CollisionHandler&#xff09;将其转换为Lambda表达式。 这将使代码更好&#xff0c;更短。 我可能还可以通过捆绑…

行内元素,块级元素,各自特点及其相互转化

作为一名小前端&#xff0c;块级元素、行内元素用了几千几万次&#xff0c;除了“块级独占一行&#xff0c;行内不独占”之外&#xff0c;对细节属性的了解十分匮乏&#xff0c;今天做以部分属性的测试和阐述。 一、 对物理属性的支持 元素类别widthheightpaddingmargin是否独…

mysql断开同步并记录位置_数据库同步自动断开问题的处理

堡垒机的实施过程中&#xff0c;因为做了双机&#xff0c;所以要对两台堡垒机进行数据库的主从同步和HA配置。在部署完mysql主从同步以后&#xff0c;发现同步会有中断的现象。中断表现为Slave_IO_Running: YesSlave_SQL_Running: NoReplicate_Do_DB:Replicate_Ignore_DB:Repli…

[NOIP2016提高组]换教室

题目&#xff1a;洛谷P1850、UOJ#262、BZOJ4720、Vijos P2005。 题目大意&#xff1a;有n个时间段&#xff0c;第i个时间段只能在教室$c_i$上课&#xff0c;另一个上这门课的教室在$d_i$。现在你最多可以进行m次申请&#xff0c;对于第i个时间段的申请如果成功&#xff0c;那么…

从RSS Feed和YQL创建数据表

Yahoo Query Language&#xff08; YQL &#xff09;是一种查询语言&#xff0c;例如SQL。 使用YQL&#xff0c;我们可以跨Web服务 查询 &#xff0c; 过滤和联接数据。 YQL也可以阅读RSS feed。 响应可以是JSON或XML。 雅虎提供了一个YQL控制台&#xff0c;用于调试 &…

background-image使用svg如何改变颜色

结论 在我多番测试之后&#xff0c;才发现background-image使用svg&#xff0c;改变颜色根本做不了。 分析 当svg图片被使用成background-image&#xff0c;颜色的设置需要在svg内部才能生效。在外部CSS设置颜色样式&#xff0c;却是无效&#xff0c;这其实可以从CSS选择器得到…

NOIP 2012 Day2

tags: 扩展欧几里得二分答案查分倍增二分答案贪心NOIP categories:信息学竞赛总结同余方程借教室疫情控制 同余方程 Solution 首先同余式可以转化为等式.\[ax\equiv 1\mod b\Leftrightarrow axby1\]   根据扩展欧几里得定理, 对于式\[axbyk(a,b),k\in \mathbf{R}\]一定存在整…

Qt之QSS(Q_PROPERTY-自定义属性)

版权声明&#xff1a;进步始于交流&#xff0c;收获源于分享&#xff01;纯正开源之美&#xff0c;有趣、好玩、靠谱。。。作者&#xff1a;一去丶二三里 博客地址&#xff1a;http://blog.csdn.net/liang19890820 目录(?)[] 简述 在Qt之QSS&#xff08;Q_PROPERTY-原始属性&a…

python print error 空_python笔记37:10分钟掌握异常处理,再也不担心程序挂了

主要内容&#xff1a;小目标&#xff1a;异常处理主要内容&#xff1a;错误与异常&#xff0c;try_except语句对于撸代码的程序员来说&#xff0c;程序运行中出现问题是常见的现象&#xff1b;实际学习与工作中&#xff0c;我们会花很大的精力去解决各种问题&#xff1b;1. 程序…

在URL参数中传递复杂对象

假设您要传递原始数据类型&#xff0c;例如复杂的Java对象 java.util.Data&#xff0c;java.lang.List&#xff0c;泛型类&#xff0c;数组以及通过URL参数所需的所有内容&#xff0c;以便在页面加载后在任何网页上预设默认值。 共同的任务&#xff1f; 是的&#xff0c;但是可…

contenteditable元素的placeholder输入提示语设置

在某些情况下&#xff0c;textarea是不够用的&#xff0c;我们还需要显示一些图标或者高亮元素&#xff0c;这就需要用富文本编辑器&#xff0c;而富文本编辑器本质上是HTML元素设置了contenteditable。 然后可能需要像input、textarea有placeholder的输入提示语&#xff0c;但…

CF 961E Tufurama

JYZdalao上课讲了这道题&#xff0c;觉得很好可做 其实也是一道理解了就水爆了的题目 把题意抽象化&#xff0c;可以发现题目求的满足 i<ja[i]>ja[j]>i的i&#xff0c;j对数。由于i&#xff0c;j顺序问题&#xff0c;可以在不考虑i&#xff0c;j顺序的情况下将ans>…

使用JCA的密码术–提供者中的服务

Java密码体系结构&#xff08;JCA&#xff09;是一个可扩展的框架&#xff0c;使您能够使用执行加密操作。 JCA还促进实现独立性&#xff08;程序不应该在乎谁提供加密服务&#xff09;和实现互操作性&#xff08;程序不应该与特定加密服务的特定提供者联系在一起&#xff09;。…