Consistent ControllerAdvice applicability against user-declared class

Issue: SPR-16496
This commit is contained in:
Juergen Hoeller
2018-02-14 14:41:16 +01:00
parent 766e6028d7
commit 46cbdff5c3
2 changed files with 63 additions and 23 deletions

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2002-2016 the original author or authors.
* Copyright 2002-2018 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.
@@ -25,6 +25,7 @@ import org.junit.Before;
import org.junit.BeforeClass;
import org.junit.Test;
import org.springframework.aop.framework.ProxyFactory;
import org.springframework.beans.FatalBeanException;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
import org.springframework.context.annotation.Bean;
@@ -38,6 +39,7 @@ import org.springframework.util.ClassUtils;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.RestControllerAdvice;
import org.springframework.web.context.support.WebApplicationObjectSupport;
import org.springframework.web.method.HandlerMethod;
import org.springframework.web.method.annotation.ModelMethodProcessor;
import org.springframework.web.method.support.HandlerMethodArgumentResolver;
@@ -213,8 +215,8 @@ public class ExceptionHandlerExceptionResolverTests {
@Test
public void resolveExceptionGlobalHandler() throws Exception {
AnnotationConfigApplicationContext cxt = new AnnotationConfigApplicationContext(MyConfig.class);
this.resolver.setApplicationContext(cxt);
AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext(MyConfig.class);
this.resolver.setApplicationContext(ctx);
this.resolver.afterPropertiesSet();
IllegalAccessException ex = new IllegalAccessException();
@@ -228,8 +230,8 @@ public class ExceptionHandlerExceptionResolverTests {
@Test
public void resolveExceptionGlobalHandlerOrdered() throws Exception {
AnnotationConfigApplicationContext cxt = new AnnotationConfigApplicationContext(MyConfig.class);
this.resolver.setApplicationContext(cxt);
AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext(MyConfig.class);
this.resolver.setApplicationContext(ctx);
this.resolver.afterPropertiesSet();
IllegalStateException ex = new IllegalStateException();
@@ -243,8 +245,8 @@ public class ExceptionHandlerExceptionResolverTests {
@Test // SPR-12605
public void resolveExceptionWithHandlerMethodArg() throws Exception {
AnnotationConfigApplicationContext cxt = new AnnotationConfigApplicationContext(MyConfig.class);
this.resolver.setApplicationContext(cxt);
AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext(MyConfig.class);
this.resolver.setApplicationContext(ctx);
this.resolver.afterPropertiesSet();
ArrayIndexOutOfBoundsException ex = new ArrayIndexOutOfBoundsException();
@@ -258,8 +260,8 @@ public class ExceptionHandlerExceptionResolverTests {
@Test
public void resolveExceptionWithAssertionError() throws Exception {
AnnotationConfigApplicationContext cxt = new AnnotationConfigApplicationContext(MyConfig.class);
this.resolver.setApplicationContext(cxt);
AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext(MyConfig.class);
this.resolver.setApplicationContext(ctx);
this.resolver.afterPropertiesSet();
AssertionError err = new AssertionError("argh");
@@ -274,8 +276,8 @@ public class ExceptionHandlerExceptionResolverTests {
@Test
public void resolveExceptionWithAssertionErrorAsRootCause() throws Exception {
AnnotationConfigApplicationContext cxt = new AnnotationConfigApplicationContext(MyConfig.class);
this.resolver.setApplicationContext(cxt);
AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext(MyConfig.class);
this.resolver.setApplicationContext(ctx);
this.resolver.afterPropertiesSet();
AssertionError err = new AssertionError("argh");
@@ -290,8 +292,8 @@ public class ExceptionHandlerExceptionResolverTests {
@Test
public void resolveExceptionControllerAdviceHandler() throws Exception {
AnnotationConfigApplicationContext cxt = new AnnotationConfigApplicationContext(MyControllerAdviceConfig.class);
this.resolver.setApplicationContext(cxt);
AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext(MyControllerAdviceConfig.class);
this.resolver.setApplicationContext(ctx);
this.resolver.afterPropertiesSet();
IllegalStateException ex = new IllegalStateException();
@@ -305,8 +307,8 @@ public class ExceptionHandlerExceptionResolverTests {
@Test
public void resolveExceptionControllerAdviceNoHandler() throws Exception {
AnnotationConfigApplicationContext cxt = new AnnotationConfigApplicationContext(MyControllerAdviceConfig.class);
this.resolver.setApplicationContext(cxt);
AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext(MyControllerAdviceConfig.class);
this.resolver.setApplicationContext(ctx);
this.resolver.afterPropertiesSet();
IllegalStateException ex = new IllegalStateException();
@@ -317,6 +319,21 @@ public class ExceptionHandlerExceptionResolverTests {
assertEquals("DefaultTestExceptionResolver: IllegalStateException", this.response.getContentAsString());
}
@Test // SPR-16496
public void resolveExceptionControllerAdviceAgainstProxy() throws Exception {
AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext(MyControllerAdviceConfig.class);
this.resolver.setApplicationContext(ctx);
this.resolver.afterPropertiesSet();
IllegalStateException ex = new IllegalStateException();
HandlerMethod handlerMethod = new HandlerMethod(new ProxyFactory(new ResponseBodyController()).getProxy(), "handle");
ModelAndView mav = this.resolver.resolveException(this.request, this.response, handlerMethod, ex);
assertNotNull("Exception was not handled", mav);
assertTrue(mav.isEmpty());
assertEquals("BasePackageTestExceptionResolver: IllegalStateException", this.response.getContentAsString());
}
private void assertMethodProcessorCount(int resolverCount, int handlerCount) {
assertEquals(resolverCount, this.resolver.getArgumentResolvers().getResolvers().size());
@@ -348,8 +365,18 @@ public class ExceptionHandlerExceptionResolverTests {
}
interface ResponseBodyInterface {
void handle();
@ExceptionHandler
@ResponseBody
String handleException(IllegalArgumentException ex);
}
@Controller
static class ResponseBodyController {
static class ResponseBodyController extends WebApplicationObjectSupport implements ResponseBodyInterface {
public void handle() {}
@@ -454,7 +481,7 @@ public class ExceptionHandlerExceptionResolverTests {
}
@RestControllerAdvice("org.springframework.web.servlet.mvc.method.annotation")
@RestControllerAdvice(assignableTypes = WebApplicationObjectSupport.class)
@Order(2)
static class BasePackageTestExceptionResolver {