All Projects → jirutka → Spring Rest Exception Handler

jirutka / Spring Rest Exception Handler

Licence: apache-2.0
A convenient Spring MVC exception handler for RESTful APIs.

Programming Languages

java
68154 projects - #9 most used programming language
groovy
2714 projects

Projects that are alternatives of or similar to Spring Rest Exception Handler

Spring Petclinic Rest
REST version of the Spring Petclinic sample application
Stars: ✭ 257 (-26.78%)
Mutual labels:  rest, spring-mvc, springframework
Tutorial
Spring Boot的例子,包含RESTful API, MVC, JMS, Cache, Mybatis, Cache, Websocket...
Stars: ✭ 215 (-38.75%)
Mutual labels:  rest, spring-mvc
Hikaku
A library that tests if the implementation of a REST-API meets its specification.
Stars: ✭ 154 (-56.13%)
Mutual labels:  rest, spring-mvc
online-shopping
This is an online shopping project using Spring Boot,Spring web-flow, Spring Rest Services and Hibernate. In this project we also used Spring Security with java and annotation configuration
Stars: ✭ 34 (-90.31%)
Mutual labels:  springframework, spring-mvc
Versioning Spring Boot Starter
Spring boot starter using for versioning rest easily.
Stars: ✭ 11 (-96.87%)
Mutual labels:  rest, spring-mvc
Gemini
Model Driven REST framework to automatically generate CRUD APIs
Stars: ✭ 138 (-60.68%)
Mutual labels:  rest, spring-mvc
kotlin-postgres
A Simple CRUD API using Spring Boot Application using PostgreSQL Database
Stars: ✭ 20 (-94.3%)
Mutual labels:  springframework, spring-mvc
Springboard
Spring Boot based production grade starter kit.
Stars: ✭ 59 (-83.19%)
Mutual labels:  spring-mvc, springframework
Spring5Certification
Spring Certification: This repository contains my examples and some best references to prepare the Spring 5 certification
Stars: ✭ 30 (-91.45%)
Mutual labels:  springframework, spring-mvc
spring02
Spring MVC 연습
Stars: ✭ 17 (-95.16%)
Mutual labels:  springframework, spring-mvc
BusinessInfrastructurePlatformGroupVersion
A java web project based on Spring Boot using MySQL, Spring MVC, Hibernate, Spring Data JPA, Query DSL, Lombok, Logback, etc.
Stars: ✭ 90 (-74.36%)
Mutual labels:  springframework, spring-mvc
Spring Framework Petclinic
A Spring Framework application based on JSP, Spring MVC, Spring Data JPA, Hibernate and JDBC
Stars: ✭ 251 (-28.49%)
Mutual labels:  spring-mvc, springframework
Ssm Demo
🍌Spring+SpringMVC+Mybatis+easyUI实现简单的后台管理系统
Stars: ✭ 1,639 (+366.95%)
Mutual labels:  spring-mvc, springframework
Javadevjournal
Source code for the tutorials published on the Javadevjournal site.
Stars: ✭ 141 (-59.83%)
Mutual labels:  rest, spring-mvc
Spring Cloud Flycloud
🔥🔥🔥FlyClould 微服务实战项目框架,在该框架中,包括了用 Spring Cloud 构建微服务的一系列基本组件和框架,对于后台服务框架的搭建有很大的参考价值,大家可以参考甚至稍加修改可以直接应用于自己的实际的项目开发中,该项目没有采用Maven进行项目构建,Maven通过xml进行依赖管理,导致整个配置文件太过臃肿,另外灵活性也不是很强,所以我采用Gradle进行项目构建和依赖管理,在FlyTour项目中我们见证了Gradle的强大,通过简单的一些配置就可以轻松的实现组件化的功能。该项目共有11个Module工程。其中10个位微服务工程,这10个微服务工程构成了一个完整的微服务系统,微服务系统包含了8个基础服务,提供了一整套微服务治理功能,他们分别是配置中心module_c…
Stars: ✭ 1,514 (+331.34%)
Mutual labels:  spring-mvc, springframework
Spring
Personal notes of preparation to Spring 5 Professional Certification
Stars: ✭ 35 (-90.03%)
Mutual labels:  springframework, spring-mvc
Mini Spring
mini-spring是简化版的spring框架,能帮助你快速熟悉spring源码和掌握spring的核心原理。抽取了spring的核心逻辑,代码极度简化,保留spring的核心功能,如IoC和AOP、资源加载器、事件监听器、类型转换、容器扩展点、bean生命周期和作用域、应用上下文等核心功能。
Stars: ✭ 698 (+98.86%)
Mutual labels:  spring-mvc, springframework
Spring Mvc Thymeleaf Crud
Spring MVC CRUD Application with Thymeleaf, HTML5, CSS3 and Bootstrap
Stars: ✭ 14 (-96.01%)
Mutual labels:  spring-mvc, springframework
gro-light-automation
A raspberry pi project to automate hydroponics with relays and data sensors through a web application
Stars: ✭ 44 (-87.46%)
Mutual labels:  springframework, spring-mvc
Spring Boot File Upload Download Rest Api Example
Spring Boot File Upload / Download Rest API Example
Stars: ✭ 300 (-14.53%)
Mutual labels:  rest, spring-mvc

= Spring REST Exception handler :source-language: java // Project meta :name: spring-rest-exception-handler :version: 1.2.0 :group-id: cz.jirutka.spring :artifact-id: {name} :gh-name: jirutka/{name} :gh-branch: master :codacy-id: ca5dbac87d564725b6640a67b2b7ea35 // URIs :src-base: link:src/main/java/cz/jirutka/spring/exhandler :spring-jdoc-uri: https://docs.spring.io/spring/docs/current/javadoc-api/org/springframework

ifdef::env-github[] image:https://travis-ci.org/{gh-name}.svg?branch={gh-branch}["Build Status", link="https://travis-ci.org/{gh-name}"] image:https://coveralls.io/repos/github/{gh-name}/badge.svg?branch={gh-branch}[Coverage Status, link="https://coveralls.io/github/{gh-name}"] image:https://api.codacy.com/project/badge/grade/{codacy-id}["Codacy code quality", link="https://www.codacy.com/app/{gh-name}"] image:https://maven-badges.herokuapp.com/maven-central/{group-id}/{artifact-id}/badge.svg[Maven Central, link="https://maven-badges.herokuapp.com/maven-central/{group-id}/{artifact-id}"] endif::env-github[]

The aim of this project is to provide a convenient exception handler (resolver) for RESTful APIs that meets a best-practices for error responses without repeating yourself. It’s very easy to handle custom exceptions, customize error responses and even localize them. Also solves some pitfalls footnote:[Nothing terrible, Spring MVC is still a far better then JAX-RS for RESTful APIs! ;)] in Spring MVC with a content negotiation when producing error responses.

== Error message

Error messages generated by ErrorMessageRestExceptionHandler follows the http://tools.ietf.org/html/draft-nottingham-http-problem-06[Problem Details for HTTP APIs] specification.

For example, the following error message describes a validation exception.

In JSON format:

[source, json]

{ "type": "http://example.org/errors/validation-failed", "title": "Validation Failed", "status": 422, "detail": "The content you've send contains 2 validation errors.", "errors": [{ "field": "title", "message": "must not be empty" }, { "field": "quantity", "rejected": -5, "message": "must be greater than zero" }] }

… or in XML:

[source,xml]

http://example.org/errors/validation-failed <title>Validation Failed</title> 422 The content you've send contains 2 validation errors. title must not be empty quantity -5 must be greater than zero ----

== How does it work?

=== RestHandlerExceptionResolver

The core class of this library that resolves all exceptions is {src-base}/RestHandlerExceptionResolver.java[RestHandlerExceptionResolver]. It holds a registry of RestExceptionHandlers.

When your controller throws an exception, the RestHandlerExceptionResolver will:

. Find an exception handler by the thrown exception type (or its supertype, supertype of the supertype… up to the Exception class if no more specific handler is found) and invoke it. . Find the best matching media type to produce (using {spring-jdoc-uri}/web/accept/ContentNegotiationManager.html[ContentNegotiationManager], utilises Accept header by default). When the requested media type is not supported, then fallback to the configured default media type. . Write the response.

=== RestExceptionHandler

Implementations of the {src-base}/handlers/RestExceptionHandler.java[RestExceptionHandler] interface are responsible for converting the exception into Spring’s {spring-jdoc-uri}/http/ResponseEntity.html[ResponseEntity] instance that contains a body, headers and a HTTP status code.

The main implementation is {src-base}/handlers/ErrorMessageRestExceptionHandler.java[ErrorMessageRestExceptionHandler] that produces the ErrorMessage body (see above for example). All the attributes (besides status) are loaded from a properties file (see the section <>). This class also logs the exception (see the <> section).

== Configuration

=== Java-based configuration

[source]

@EnableWebMvc @Configuration public class RestContextConfig extends WebMvcConfigurerAdapter {

@Override
public void configureHandlerExceptionResolvers(List<HandlerExceptionResolver> resolvers) {
    resolvers.add( exceptionHandlerExceptionResolver() ); // resolves @ExceptionHandler
    resolvers.add( restExceptionResolver() );
}

@Bean
public RestHandlerExceptionResolver restExceptionResolver() {
    return RestHandlerExceptionResolver.builder()
            .messageSource( httpErrorMessageSource() )
            .defaultContentType(MediaType.APPLICATION_JSON)
            .addErrorMessageHandler(EmptyResultDataAccessException.class, HttpStatus.NOT_FOUND)
            .addHandler(MyException.class, new MyExceptionHandler())
            .build();
}

@Bean
public MessageSource httpErrorMessageSource() {
    ReloadableResourceBundleMessageSource m = new ReloadableResourceBundleMessageSource();
    m.setBasename("classpath:/org/example/messages");
    m.setDefaultEncoding("UTF-8");
    return m;
}

@Bean
public ExceptionHandlerExceptionResolver exceptionHandlerExceptionResolver() {
    ExceptionHandlerExceptionResolver resolver = new ExceptionHandlerExceptionResolver();
    resolver.setMessageConverters(HttpMessageConverterUtils.getDefaultHttpMessageConverters());
    return resolver;
}

}

=== XML-based configuration

[source, xml]

=== Another resolvers

The {spring-jdoc-uri}/web/servlet/mvc/method/annotation/ExceptionHandlerExceptionResolver.html[ExceptionHandlerExceptionResolver] is used to resolve exceptions through {spring-jdoc-uri}/web/bind/annotation/ExceptionHandler.html[@ExceptionHandler] methods. It must be registered before the RestHandlerExceptionResolver. If you don’t have any @ExceptionHandler methods, then you can omit the exceptionHandlerExceptionResolver bean declaration.

=== Default handlers

Builder and FactoryBean registers a set of the default handlers by default. This can be disabled by setting withDefaultHandlers to false.

=== Localizable error messages

Message values are read from a properties file through the provided {spring-jdoc-uri}/context/MessageSource.html[MessageSource], so it can be simply customized and localized. Library contains a default link:src/main/resources/cz/jirutka/spring/exhandler/messages.properties[messages.properties] file that is implicitly set as a parent (i.e. fallback) of the provided message source. This can be disabled by setting withDefaultMessageSource to false (on a builder or factory bean).

The key name is prefixed with a fully qualified class name of the Java exception, or default for the default value; this is used when no value for a particular exception class exists (even in the parent message source).

Value is a message template that may contain https://docs.spring.io/spring/docs/current/spring-framework-reference/html/expressions.html[SpEL] expressions delimited by #{ and }. Inside an expression, you can access the exception being handled and the current request (instance of http://docs.oracle.com/javaee/7/api/javax/servlet/http/HttpServletRequest.html[HttpServletRequest]) under the ex, resp. req variables.

For example:

[source, properties]

org.springframework.web.HttpMediaTypeNotAcceptableException.type=http://httpstatus.es/406 org.springframework.web.HttpMediaTypeNotAcceptableException.title=Not Acceptable org.springframework.web.HttpMediaTypeNotAcceptableException.detail=
This resource provides #{ex.supportedMediaTypes}, but you've requested #{req.getHeader('Accept')}.

=== Exception logging

Exceptions handled with status code 5×× are logged on ERROR level (incl. stack trace), other exceptions are logged on INFO level without a stack trace, or on DEBUG level with a stack trace if enabled. The logger name is cz.jirutka.spring.exhandler.handlers.RestExceptionHandler and a Marker is set to the exception’s full qualified name.

=== Why is 404 bypassing exception handler?

When the {spring-jdoc-uri}/web/servlet/DispatcherServlet.html[DispatcherServlet] is unable to determine a corresponding handler for an incoming HTTP request, it sends 404 directly without bothering to call an exception handler (see http://stackoverflow.com/a/22751886/2217862[on StackOverflow]). This behaviour can be changed, since Spring 4.0.0, using throwExceptionIfNoHandlerFound init parameter. You should set this to true for a consistent error responses.

When using WebApplicationInitializer:

[source]

public class AppInitializer extends AbstractAnnotationConfigDispatcherServletInitializer {

protected void customizeRegistration(ServletRegistration.Dynamic reg) {
    reg.setInitParameter("throwExceptionIfNoHandlerFound", "true");
}
...

}

…or classic web.xml:

[source, xml]

rest-dispatcher org.springframework.web.servlet.DispatcherServlet throwExceptionIfNoHandlerFound true ... ----

== How to get it?

Released versions are available in jCenter and the Central Repository. Just add this artifact to your project:

.Maven [source, xml, subs="verbatim, attributes"]

{group-id} {artifact-id} {version} ----

.Gradle [source, groovy, subs="verbatim, attributes"] compile '{group-id}:{artifact-id}:{version}'

However if you want to use the last snapshot version, you have to add the JFrog OSS repository:

.Maven [source, xml]

jfrog-oss-snapshot-local JFrog OSS repository for snapshots https://oss.jfrog.org/oss-snapshot-local true ----

.Gradle [source, groovy]

repositories { maven { url 'https://oss.jfrog.org/oss-snapshot-local' } }

== Requirements

  • Spring 3.2.0.RELEASE and newer is supported, but 4.× is highly recommended.
  • Jackson 1.× and 2.× are both supported and optional.

== References

== License

This project is licensed under http://www.apache.org/licenses/LICENSE-2.0.html[Apache License 2.0].

Note that the project description data, including the texts, logos, images, and/or trademarks, for each open source project belongs to its rightful owner. If you wish to add or remove any projects, please contact us at [email protected].