diff --git a/spring-data-rest-webmvc/src/main/java/org/springframework/data/rest/webmvc/AbstractRepositoryRestController.java b/spring-data-rest-webmvc/src/main/java/org/springframework/data/rest/webmvc/AbstractRepositoryRestController.java index e58d4a2c1..438705ffc 100644 --- a/spring-data-rest-webmvc/src/main/java/org/springframework/data/rest/webmvc/AbstractRepositoryRestController.java +++ b/spring-data-rest-webmvc/src/main/java/org/springframework/data/rest/webmvc/AbstractRepositoryRestController.java @@ -15,8 +15,12 @@ */ package org.springframework.data.rest.webmvc; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; +import static org.springframework.data.rest.webmvc.ControllerUtils.*; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; + import org.springframework.data.domain.Page; import org.springframework.data.rest.core.mapping.ResourceMetadata; import org.springframework.data.web.PagedResourcesAssembler; @@ -25,12 +29,6 @@ import org.springframework.hateoas.Resource; import org.springframework.hateoas.Resources; import org.springframework.util.Assert; -import java.util.ArrayList; -import java.util.Collections; -import java.util.List; - -import static org.springframework.data.rest.webmvc.ControllerUtils.EMPTY_RESOURCE_LIST; - /** * @author Jon Brisbin * @author Oliver Gierke @@ -39,8 +37,6 @@ import static org.springframework.data.rest.webmvc.ControllerUtils.EMPTY_RESOURC @SuppressWarnings({ "rawtypes" }) class AbstractRepositoryRestController { - private static final Logger LOG = LoggerFactory.getLogger(AbstractRepositoryRestController.class); - private final PagedResourcesAssembler pagedResourcesAssembler; /** diff --git a/spring-data-rest-webmvc/src/main/java/org/springframework/data/rest/webmvc/GlobalExceptionHandler.java b/spring-data-rest-webmvc/src/main/java/org/springframework/data/rest/webmvc/GlobalExceptionHandler.java deleted file mode 100644 index 20ccaf17d..000000000 --- a/spring-data-rest-webmvc/src/main/java/org/springframework/data/rest/webmvc/GlobalExceptionHandler.java +++ /dev/null @@ -1,160 +0,0 @@ -package org.springframework.data.rest.webmvc; - -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import org.springframework.context.MessageSource; -import org.springframework.context.MessageSourceAware; -import org.springframework.context.support.MessageSourceAccessor; -import org.springframework.core.convert.ConversionFailedException; -import org.springframework.dao.DataIntegrityViolationException; -import org.springframework.dao.OptimisticLockingFailureException; -import org.springframework.data.rest.core.RepositoryConstraintViolationException; -import org.springframework.data.rest.webmvc.support.ETagDoesntMatchException; -import org.springframework.data.rest.webmvc.support.ExceptionMessage; -import org.springframework.data.rest.webmvc.support.RepositoryConstraintViolationExceptionMessage; -import org.springframework.http.HttpHeaders; -import org.springframework.http.HttpStatus; -import org.springframework.http.ResponseEntity; -import org.springframework.http.converter.HttpMessageNotReadableException; -import org.springframework.web.HttpRequestMethodNotSupportedException; -import org.springframework.web.bind.annotation.ControllerAdvice; -import org.springframework.web.bind.annotation.ExceptionHandler; -import org.springframework.web.bind.annotation.ResponseBody; - -import java.lang.reflect.InvocationTargetException; -import java.util.Locale; - -/** - * @author Thibaud Lepretre - */ -@ControllerAdvice -public class GlobalExceptionHandler implements MessageSourceAware { - - private static final Logger LOG = LoggerFactory.getLogger(GlobalExceptionHandler.class); - - - private MessageSourceAccessor messageSourceAccessor; - - /* - * (non-Javadoc) - * @see org.springframework.context.MessageSourceAware#setMessageSource(org.springframework.context.MessageSource) - */ - @Override - public void setMessageSource(MessageSource messageSource) { - this.messageSourceAccessor = new MessageSourceAccessor(messageSource); - } - - @ExceptionHandler({ NullPointerException.class }) - @ResponseBody - public ResponseEntity handleNPE(NullPointerException npe) { - return errorResponse(npe, HttpStatus.INTERNAL_SERVER_ERROR); - } - - @ExceptionHandler({ ResourceNotFoundException.class }) - @ResponseBody - public ResponseEntity handleNotFound() { - return notFound(); - } - - @ExceptionHandler({ HttpMessageNotReadableException.class }) - @ResponseBody - public ResponseEntity handleNotReadable(HttpMessageNotReadableException e) { - return badRequest(e); - } - - /** - * Handle failures commonly thrown from code tries to read incoming data and convert or cast it to the right type. - * - * @param t - * @return - */ - @ExceptionHandler({ InvocationTargetException.class, IllegalArgumentException.class, ClassCastException.class, - ConversionFailedException.class }) - @ResponseBody - public ResponseEntity handleMiscFailures(Throwable t) { - if (null != t.getCause() && t.getCause() instanceof ResourceNotFoundException) { - return notFound(); - } - return badRequest(t); - } - - @ExceptionHandler({ RepositoryConstraintViolationException.class }) - @ResponseBody - public ResponseEntity handleRepositoryConstraintViolationException(Locale locale, - RepositoryConstraintViolationException rcve) { - - return response(null, new RepositoryConstraintViolationExceptionMessage(rcve, messageSourceAccessor), - HttpStatus.BAD_REQUEST); - } - - /** - * Send a 409 Conflict in case of concurrent modification. - * - * @param ex - * @return HTTP Status 409 ResponseEntity - */ - @ExceptionHandler({ OptimisticLockingFailureException.class, DataIntegrityViolationException.class }) - public ResponseEntity handleConflict(Exception ex) { - return errorResponse(null, ex, HttpStatus.CONFLICT); - } - - /** - * Send {@code 405 Method Not Allowed} and include the supported {@link org.springframework.http.HttpMethod}s in the {@code Allow} header. - * - * @param o_O - * @return HTTP Status 405 ResponseEntity - */ - @ExceptionHandler - public ResponseEntity handle(HttpRequestMethodNotSupportedException o_O) { - - HttpHeaders headers = new HttpHeaders(); - headers.setAllow(o_O.getSupportedHttpMethods()); - - return new ResponseEntity(headers, HttpStatus.METHOD_NOT_ALLOWED); - } - - @ExceptionHandler - public ResponseEntity handle(ETagDoesntMatchException o_O) { - - HttpHeaders headers = o_O.getExpectedETag().addTo(new HttpHeaders()); - return new ResponseEntity(headers, HttpStatus.PRECONDITION_FAILED); - } - - protected ResponseEntity notFound() { - return notFound(null, null); - } - - protected ResponseEntity notFound(HttpHeaders headers, T body) { - return response(headers, body, HttpStatus.NOT_FOUND); - } - - protected ResponseEntity badRequest(T throwable) { - return badRequest(null, throwable); - } - - protected ResponseEntity badRequest(HttpHeaders headers, T throwable) { - return errorResponse(headers, throwable, HttpStatus.BAD_REQUEST); - } - - public ResponseEntity errorResponse(T throwable, HttpStatus status) { - return errorResponse(null, throwable, status); - } - - public ResponseEntity errorResponse(HttpHeaders headers, T throwable, - HttpStatus status) { - if (null != throwable && null != throwable.getMessage()) { - LOG.error(throwable.getMessage(), throwable); - return response(headers, new ExceptionMessage(throwable), status); - } else { - return response(headers, null, status); - } - } - - public ResponseEntity response(HttpHeaders headers, T body, HttpStatus status) { - HttpHeaders hdrs = new HttpHeaders(); - if (null != headers) { - hdrs.putAll(headers); - } - return new ResponseEntity(body, hdrs, status); - } -} diff --git a/spring-data-rest-webmvc/src/main/java/org/springframework/data/rest/webmvc/RepositoryRestExceptionHandler.java b/spring-data-rest-webmvc/src/main/java/org/springframework/data/rest/webmvc/RepositoryRestExceptionHandler.java new file mode 100644 index 000000000..1d7ce7206 --- /dev/null +++ b/spring-data-rest-webmvc/src/main/java/org/springframework/data/rest/webmvc/RepositoryRestExceptionHandler.java @@ -0,0 +1,195 @@ +/* + * Copyright 2014 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.springframework.data.rest.webmvc; + +import java.lang.reflect.InvocationTargetException; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.context.MessageSource; +import org.springframework.context.support.MessageSourceAccessor; +import org.springframework.core.convert.ConversionFailedException; +import org.springframework.dao.DataIntegrityViolationException; +import org.springframework.dao.OptimisticLockingFailureException; +import org.springframework.data.rest.core.RepositoryConstraintViolationException; +import org.springframework.data.rest.webmvc.support.ETagDoesntMatchException; +import org.springframework.data.rest.webmvc.support.ExceptionMessage; +import org.springframework.data.rest.webmvc.support.RepositoryConstraintViolationExceptionMessage; +import org.springframework.http.HttpHeaders; +import org.springframework.http.HttpStatus; +import org.springframework.http.ResponseEntity; +import org.springframework.http.converter.HttpMessageNotReadableException; +import org.springframework.util.Assert; +import org.springframework.web.HttpRequestMethodNotSupportedException; +import org.springframework.web.bind.annotation.ControllerAdvice; +import org.springframework.web.bind.annotation.ExceptionHandler; + +/** + * Exception handler for Spring Data REST controllers. + * + * @author Thibaud Lepretre + * @author Oliver Gierke + */ +@ControllerAdvice(basePackageClasses = RepositoryRestExceptionHandler.class) +public class RepositoryRestExceptionHandler { + + private static final Logger LOG = LoggerFactory.getLogger(RepositoryRestExceptionHandler.class); + + private final MessageSourceAccessor messageSourceAccessor; + + /** + * Creates a new {@link RepositoryRestExceptionHandler} using the given {@link MessageSource}. + * + * @param messageSource must not be {@literal null}. + */ + public RepositoryRestExceptionHandler(MessageSource messageSource) { + + Assert.notNull(messageSource, "MessageSource must not be null!"); + this.messageSourceAccessor = new MessageSourceAccessor(messageSource); + } + + /** + * Handles {@link ResourceNotFoundException} by returning {@code 404 Not Found}. + * + * @param o_O the exception to handle. + * @return + */ + @ExceptionHandler + ResponseEntity handleNotFound(ResourceNotFoundException o_O) { + return notFound(); + } + + /** + * Handles {@link HttpMessageNotReadableException} by returning {@code 400 Bad Request}. + * + * @param o_O the exception to handle. + * @return + */ + @ExceptionHandler + ResponseEntity handleNotReadable(HttpMessageNotReadableException o_O) { + return badRequest(o_O); + } + + /** + * Handle failures commonly thrown from code tries to read incoming data and convert or cast it to the right type by + * returning {@code 500 Internal Server Error} and the thrown exception marshalled into JSON. + * + * @param o_O the exception to handle. + * @return + */ + @ExceptionHandler({ InvocationTargetException.class, IllegalArgumentException.class, ClassCastException.class, + ConversionFailedException.class, NullPointerException.class }) + ResponseEntity handleMiscFailures(Exception o_O) { + return errorResponse(null, HttpStatus.INTERNAL_SERVER_ERROR); + } + + /** + * Handles {@link RepositoryConstraintViolationException}s by returning {@code 400 Bad Request}. + * + * @param o_O the exception to handle. + * @return + */ + @ExceptionHandler + ResponseEntity handleRepositoryConstraintViolationException( + RepositoryConstraintViolationException o_O) { + + return response(new HttpHeaders(), new RepositoryConstraintViolationExceptionMessage(o_O, messageSourceAccessor), + HttpStatus.BAD_REQUEST); + } + + /** + * Send a {@code 409 Conflict} in case of concurrent modification. + * + * @param o_O the exception to handle. + * @return + */ + @ExceptionHandler({ OptimisticLockingFailureException.class, DataIntegrityViolationException.class }) + ResponseEntity handleConflict(Exception o_O) { + return errorResponse(null, o_O, HttpStatus.CONFLICT); + } + + /** + * Send {@code 405 Method Not Allowed} and include the supported {@link org.springframework.http.HttpMethod}s in the + * {@code Allow} header. + * + * @param o_O the exception to handle. + * @return + */ + @ExceptionHandler + ResponseEntity handle(HttpRequestMethodNotSupportedException o_O) { + + HttpHeaders headers = new HttpHeaders(); + headers.setAllow(o_O.getSupportedHttpMethods()); + + return new ResponseEntity(headers, HttpStatus.METHOD_NOT_ALLOWED); + } + + /** + * Handles {@link ETagDoesntMatchException} by returning {@code 412 Precondition Failed}. + * + * @param o_O the exception to handle. + * @return + */ + @ExceptionHandler + ResponseEntity handle(ETagDoesntMatchException o_O) { + + HttpHeaders headers = o_O.getExpectedETag().addTo(new HttpHeaders()); + return new ResponseEntity(headers, HttpStatus.PRECONDITION_FAILED); + } + + private ResponseEntity notFound() { + return notFound(new HttpHeaders(), null); + } + + private ResponseEntity notFound(HttpHeaders headers, T body) { + return response(headers, body, HttpStatus.NOT_FOUND); + } + + private ResponseEntity badRequest(T throwable) { + return badRequest(null, throwable); + } + + private ResponseEntity badRequest(HttpHeaders headers, T throwable) { + return errorResponse(headers, throwable, HttpStatus.BAD_REQUEST); + } + + private ResponseEntity errorResponse(T throwable, HttpStatus status) { + return errorResponse(new HttpHeaders(), throwable, status); + } + + private ResponseEntity errorResponse(HttpHeaders headers, + Exception exception, HttpStatus status) { + + if (null != exception && null != exception.getMessage()) { + + LOG.error(exception.getMessage(), exception); + + return response(headers, new ExceptionMessage(exception), status); + + } else { + + return response(headers, null, status); + } + } + + public ResponseEntity response(HttpHeaders headers, T body, HttpStatus status) { + + Assert.notNull(headers, "Headers must not be null!"); + Assert.notNull(status, "HttpStatus must not be null!"); + + return new ResponseEntity(body, headers, status); + } +} diff --git a/spring-data-rest-webmvc/src/main/java/org/springframework/data/rest/webmvc/config/RepositoryRestMvcConfiguration.java b/spring-data-rest-webmvc/src/main/java/org/springframework/data/rest/webmvc/config/RepositoryRestMvcConfiguration.java index 7f084de69..63cac206b 100644 --- a/spring-data-rest-webmvc/src/main/java/org/springframework/data/rest/webmvc/config/RepositoryRestMvcConfiguration.java +++ b/spring-data-rest-webmvc/src/main/java/org/springframework/data/rest/webmvc/config/RepositoryRestMvcConfiguration.java @@ -25,7 +25,6 @@ import java.util.Set; import org.springframework.beans.factory.BeanCreationException; import org.springframework.beans.factory.BeanFactoryUtils; -import org.springframework.beans.factory.ListableBeanFactory; import org.springframework.beans.factory.ObjectFactory; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Qualifier; @@ -68,8 +67,8 @@ import org.springframework.data.rest.core.support.RepositoryRelProvider; import org.springframework.data.rest.webmvc.BaseUri; import org.springframework.data.rest.webmvc.BaseUriAwareController; import org.springframework.data.rest.webmvc.BaseUriAwareHandlerMapping; -import org.springframework.data.rest.webmvc.GlobalExceptionHandler; import org.springframework.data.rest.webmvc.RepositoryRestController; +import org.springframework.data.rest.webmvc.RepositoryRestExceptionHandler; import org.springframework.data.rest.webmvc.RepositoryRestHandlerAdapter; import org.springframework.data.rest.webmvc.RepositoryRestHandlerMapping; import org.springframework.data.rest.webmvc.RestMediaTypes; @@ -146,7 +145,7 @@ public class RepositoryRestMvcConfiguration extends HateoasAwareSpringDataWebCon private static final boolean IS_JPA_AVAILABLE = ClassUtils.isPresent("javax.persistence.EntityManager", RepositoryRestMvcConfiguration.class.getClassLoader()); - @Autowired ListableBeanFactory beanFactory; + @Autowired ApplicationContext applicationContext; @Autowired(required = false) List idConverters = Collections.emptyList(); @@ -155,7 +154,7 @@ public class RepositoryRestMvcConfiguration extends HateoasAwareSpringDataWebCon @Bean public Repositories repositories() { - return new Repositories(beanFactory); + return new Repositories(applicationContext); } @Bean @@ -168,7 +167,7 @@ public class RepositoryRestMvcConfiguration extends HateoasAwareSpringDataWebCon List> arrayList = new ArrayList>(); - for (MappingContext context : BeanFactoryUtils.beansOfTypeIncludingAncestors(beanFactory, + for (MappingContext context : BeanFactoryUtils.beansOfTypeIncludingAncestors(applicationContext, MappingContext.class).values()) { arrayList.add(context); } @@ -474,7 +473,8 @@ public class RepositoryRestMvcConfiguration extends HateoasAwareSpringDataWebCon List> messageConverters = defaultMessageConverters(); configureHttpMessageConverters(messageConverters); - Collection beans = beanFactory.getBeansOfType(ResourceProcessor.class, false, false).values(); + Collection beans = applicationContext.getBeansOfType(ResourceProcessor.class, false, false) + .values(); List> processors = new ArrayList>(beans.size()); for (ResourceProcessor bean : beans) { @@ -549,8 +549,8 @@ public class RepositoryRestMvcConfiguration extends HateoasAwareSpringDataWebCon } @Bean - public GlobalExceptionHandler globalExceptionHandler() { - return new GlobalExceptionHandler(); + public RepositoryRestExceptionHandler repositoryRestExceptionHandler() { + return new RepositoryRestExceptionHandler(applicationContext); } @Bean @@ -628,8 +628,8 @@ public class RepositoryRestMvcConfiguration extends HateoasAwareSpringDataWebCon private List defaultMethodArgumentResolvers() { PersistentEntityResourceAssemblerArgumentResolver peraResolver = new PersistentEntityResourceAssemblerArgumentResolver( - repositories(), entityLinks(), config().projectionConfiguration(), new ProxyProjectionFactory(beanFactory), - resourceMappings()); + repositories(), entityLinks(), config().projectionConfiguration(), new ProxyProjectionFactory( + applicationContext), resourceMappings()); HateoasPageableHandlerMethodArgumentResolver pageableResolver = pageableResolver(); HandlerMethodArgumentResolver defaultedPageableResolver = new DefaultedPageableHandlerMethodArgumentResolver( diff --git a/spring-data-rest-webmvc/src/main/java/org/springframework/data/rest/webmvc/support/ExceptionMessage.java b/spring-data-rest-webmvc/src/main/java/org/springframework/data/rest/webmvc/support/ExceptionMessage.java index e358e555d..210c76782 100644 --- a/spring-data-rest-webmvc/src/main/java/org/springframework/data/rest/webmvc/support/ExceptionMessage.java +++ b/spring-data-rest-webmvc/src/main/java/org/springframework/data/rest/webmvc/support/ExceptionMessage.java @@ -9,23 +9,19 @@ import com.fasterxml.jackson.annotation.JsonProperty; */ public class ExceptionMessage { - private final Throwable exception; + private final Throwable throwable; - public ExceptionMessage(Throwable exception) { - this.exception = exception; + public ExceptionMessage(Throwable throwable) { + this.throwable = throwable; } @JsonProperty("message") public String getMessage() { - return exception.getMessage(); + return throwable.getMessage(); } @JsonProperty("cause") public ExceptionMessage getCause() { - if (null != exception.getCause()) { - return new ExceptionMessage(exception.getCause()); - } - return null; + return throwable.getCause() != null ? new ExceptionMessage(throwable.getCause()) : null; } - } diff --git a/spring-data-rest-webmvc/src/main/java/org/springframework/data/rest/webmvc/support/RepositoryConstraintViolationExceptionMessage.java b/spring-data-rest-webmvc/src/main/java/org/springframework/data/rest/webmvc/support/RepositoryConstraintViolationExceptionMessage.java index 932e94f82..521517f86 100644 --- a/spring-data-rest-webmvc/src/main/java/org/springframework/data/rest/webmvc/support/RepositoryConstraintViolationExceptionMessage.java +++ b/spring-data-rest-webmvc/src/main/java/org/springframework/data/rest/webmvc/support/RepositoryConstraintViolationExceptionMessage.java @@ -1,3 +1,18 @@ +/* + * Copyright 2012-2014 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ package org.springframework.data.rest.webmvc.support; import java.util.ArrayList; @@ -11,6 +26,7 @@ import com.fasterxml.jackson.annotation.JsonProperty; /** * @author Jon Brisbin + * @author Oliver Gierke */ public class RepositoryConstraintViolationExceptionMessage { @@ -21,17 +37,8 @@ public class RepositoryConstraintViolationExceptionMessage { for (FieldError fieldError : violationException.getErrors().getFieldErrors()) { - List args = new ArrayList(); - args.add(fieldError.getObjectName()); - args.add(fieldError.getField()); - args.add(fieldError.getRejectedValue()); - if (null != fieldError.getArguments()) { - for (Object o : fieldError.getArguments()) { - args.add(o); - } - } + String message = accessor.getMessage(fieldError); - String message = accessor.getMessage(fieldError.getCode(), args.toArray(), fieldError.getDefaultMessage()); this.errors.add(new ValidationError(fieldError.getObjectName(), message, String.format("%s", fieldError.getRejectedValue()), fieldError.getField())); } @@ -72,5 +79,4 @@ public class RepositoryConstraintViolationExceptionMessage { return property; } } - } diff --git a/spring-data-rest-webmvc/src/test/java/org/springframework/data/rest/webmvc/support/ControllerAdviceConfig.java b/spring-data-rest-webmvc/src/test/java/org/springframework/data/rest/webmvc/support/ControllerAdviceConfig.java deleted file mode 100644 index 710545fd8..000000000 --- a/spring-data-rest-webmvc/src/test/java/org/springframework/data/rest/webmvc/support/ControllerAdviceConfig.java +++ /dev/null @@ -1,32 +0,0 @@ -package org.springframework.data.rest.webmvc.support; - -import org.springframework.context.annotation.Configuration; -import org.springframework.context.annotation.Import; -import org.springframework.core.Ordered; -import org.springframework.core.annotation.Order; -import org.springframework.data.rest.webmvc.jpa.JpaRepositoryConfig; -import org.springframework.http.HttpHeaders; -import org.springframework.http.HttpStatus; -import org.springframework.http.ResponseEntity; -import org.springframework.web.HttpRequestMethodNotSupportedException; -import org.springframework.web.bind.annotation.ControllerAdvice; -import org.springframework.web.bind.annotation.ExceptionHandler; - -/** - * @author Thibaud Lepretre - */ -@Configuration -@Import(JpaRepositoryConfig.class) -public class ControllerAdviceConfig { - @Order(Ordered.HIGHEST_PRECEDENCE) - @ControllerAdvice - public static class CustomGlobalConfiguration { - @ExceptionHandler - public ResponseEntity handle(HttpRequestMethodNotSupportedException o_O) { - HttpHeaders headers = new HttpHeaders(); - headers.setAllow(o_O.getSupportedHttpMethods()); - - return new ResponseEntity(headers, HttpStatus.INTERNAL_SERVER_ERROR); - } - } -} diff --git a/spring-data-rest-webmvc/src/test/java/org/springframework/data/rest/webmvc/support/ControllerAdviceWebTests.java b/spring-data-rest-webmvc/src/test/java/org/springframework/data/rest/webmvc/support/ControllerAdviceWebTests.java deleted file mode 100644 index edd78cca2..000000000 --- a/spring-data-rest-webmvc/src/test/java/org/springframework/data/rest/webmvc/support/ControllerAdviceWebTests.java +++ /dev/null @@ -1,29 +0,0 @@ -package org.springframework.data.rest.webmvc.support; - -import org.junit.Test; -import org.springframework.data.rest.webmvc.AbstractWebIntegrationTests; -import org.springframework.hateoas.Link; -import org.springframework.test.context.ContextConfiguration; - -import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get; -import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; - -/** - * @author Thibaud Lepretre - */ -@ContextConfiguration(classes = ControllerAdviceConfig.class) -public class ControllerAdviceWebTests extends AbstractWebIntegrationTests { - @Test - public void httpRequestMethodNotSupportedExceptionShouldNowReturnHttpStatus500Over405() throws Exception { - - Link link = client.discoverUnique("addresses"); - - mvc.perform(get(link.getHref())).// - andExpect(status().isInternalServerError()); - } - - @Override - protected Iterable expectedRootLinkRels() { - return null; - } -} diff --git a/spring-data-rest-webmvc/src/test/java/org/springframework/data/rest/webmvc/support/ExceptionHandlingCustomizationIntegrationTests.java b/spring-data-rest-webmvc/src/test/java/org/springframework/data/rest/webmvc/support/ExceptionHandlingCustomizationIntegrationTests.java new file mode 100644 index 000000000..a15e2b35a --- /dev/null +++ b/spring-data-rest-webmvc/src/test/java/org/springframework/data/rest/webmvc/support/ExceptionHandlingCustomizationIntegrationTests.java @@ -0,0 +1,84 @@ +/* + * Copyright 2014 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.springframework.data.rest.webmvc.support; + +import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.*; +import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.*; + +import java.util.Collections; + +import org.junit.Test; +import org.springframework.context.annotation.Configuration; +import org.springframework.context.annotation.Import; +import org.springframework.core.Ordered; +import org.springframework.core.annotation.Order; +import org.springframework.data.rest.webmvc.AbstractWebIntegrationTests; +import org.springframework.data.rest.webmvc.jpa.JpaRepositoryConfig; +import org.springframework.hateoas.Link; +import org.springframework.http.HttpHeaders; +import org.springframework.http.HttpStatus; +import org.springframework.http.ResponseEntity; +import org.springframework.test.context.ContextConfiguration; +import org.springframework.web.HttpRequestMethodNotSupportedException; +import org.springframework.web.bind.annotation.ControllerAdvice; +import org.springframework.web.bind.annotation.ExceptionHandler; + +/** + * Integration tests for customization of Spring Data REST's exception handling. + * + * @author Thibaud Lepretre + * @author Oliver Gierke + */ +@ContextConfiguration +public class ExceptionHandlingCustomizationIntegrationTests extends AbstractWebIntegrationTests { + + @Configuration + @Import(JpaRepositoryConfig.class) + static class ControllerAdviceConfig { + + @ControllerAdvice + @Order(Ordered.HIGHEST_PRECEDENCE) + static class CustomGlobalConfiguration { + + @ExceptionHandler + ResponseEntity handle(HttpRequestMethodNotSupportedException o_O) { + + HttpHeaders headers = new HttpHeaders(); + headers.setAllow(o_O.getSupportedHttpMethods()); + + return new ResponseEntity(headers, HttpStatus.INTERNAL_SERVER_ERROR); + } + } + } + + @Test + public void httpRequestMethodNotSupportedExceptionShouldNowReturnHttpStatus500Over405() throws Exception { + + Link link = client.discoverUnique("addresses"); + + mvc.perform(get(link.getHref())).// + andExpect(status().isInternalServerError()); + } + + /* + * (non-Javadoc) + * @see org.springframework.data.rest.webmvc.AbstractWebIntegrationTests#expectedRootLinkRels() + */ + @Override + protected Iterable expectedRootLinkRels() { + return Collections.emptySet(); + } +}