Skip to content

Commit bd482d7

Browse files
committed
Add DefaultHandlerExceptionResolver to child context
Fixes gh-14084
1 parent 5780ed3 commit bd482d7

File tree

2 files changed

+129
-0
lines changed

2 files changed

+129
-0
lines changed

spring-boot-actuator/src/main/java/org/springframework/boot/actuate/autoconfigure/EndpointWebMvcChildContextConfiguration.java

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,7 @@
6565
import org.springframework.web.servlet.HandlerMapping;
6666
import org.springframework.web.servlet.ModelAndView;
6767
import org.springframework.web.servlet.config.annotation.EnableWebMvc;
68+
import org.springframework.web.servlet.mvc.support.DefaultHandlerExceptionResolver;
6869

6970
/**
7071
* Configuration triggered from {@link EndpointWebMvcAutoConfiguration} when a new
@@ -317,6 +318,9 @@ private List<HandlerExceptionResolver> extractResolvers() {
317318
.values());
318319
list.remove(this);
319320
AnnotationAwareOrderComparator.sort(list);
321+
if (list.isEmpty()) {
322+
list.add(new DefaultHandlerExceptionResolver());
323+
}
320324
return list;
321325
}
322326

Original file line numberDiff line numberDiff line change
@@ -0,0 +1,125 @@
1+
/*
2+
* Copyright 2012-2018 the original author or authors.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
package org.springframework.boot.actuate.autoconfigure;
17+
18+
import javax.servlet.http.HttpServletRequest;
19+
import javax.servlet.http.HttpServletResponse;
20+
21+
import org.junit.After;
22+
import org.junit.Before;
23+
import org.junit.Test;
24+
25+
import org.springframework.boot.context.properties.EnableConfigurationProperties;
26+
import org.springframework.context.annotation.Bean;
27+
import org.springframework.context.annotation.Configuration;
28+
import org.springframework.context.annotation.Import;
29+
import org.springframework.mock.web.MockHttpServletRequest;
30+
import org.springframework.mock.web.MockHttpServletResponse;
31+
import org.springframework.mock.web.MockServletContext;
32+
import org.springframework.web.HttpRequestMethodNotSupportedException;
33+
import org.springframework.web.context.support.AnnotationConfigWebApplicationContext;
34+
import org.springframework.web.servlet.HandlerExceptionResolver;
35+
import org.springframework.web.servlet.ModelAndView;
36+
37+
import static org.assertj.core.api.Assertions.assertThat;
38+
39+
/**
40+
* Tests for {@link EndpointWebMvcChildContextConfiguration}.
41+
*
42+
* @author Madhura Bhave
43+
*/
44+
public class EndpointWebMvcChildContextConfigurationTests {
45+
46+
private AnnotationConfigWebApplicationContext context;
47+
48+
private MockHttpServletRequest request = new MockHttpServletRequest();
49+
50+
private MockHttpServletResponse response = new MockHttpServletResponse();
51+
52+
@Before
53+
public void setup() {
54+
this.context = new AnnotationConfigWebApplicationContext();
55+
this.context.setServletContext(new MockServletContext());
56+
}
57+
58+
@After
59+
public void close() {
60+
if (this.context != null) {
61+
this.context.close();
62+
}
63+
}
64+
65+
@Test
66+
public void compositeResolverShouldAddDefaultResolverIfNonePresent() {
67+
this.context.register(BaseConfiguration.class);
68+
this.context.setParent(getParentApplicationContext());
69+
this.context.refresh();
70+
EndpointWebMvcChildContextConfiguration.CompositeHandlerExceptionResolver resolver = this.context
71+
.getBean(
72+
EndpointWebMvcChildContextConfiguration.CompositeHandlerExceptionResolver.class);
73+
ModelAndView resolved = resolver.resolveException(this.request, this.response,
74+
null, new HttpRequestMethodNotSupportedException("POST"));
75+
assertThat(resolved).isNotNull();
76+
}
77+
78+
@Test
79+
public void compositeResolverShouldDelegateToOtherResolversInContext() {
80+
this.context.register(HandlerExceptionResolverConfiguration.class);
81+
this.context.setParent(getParentApplicationContext());
82+
this.context.refresh();
83+
EndpointWebMvcChildContextConfiguration.CompositeHandlerExceptionResolver resolver = this.context
84+
.getBean(
85+
EndpointWebMvcChildContextConfiguration.CompositeHandlerExceptionResolver.class);
86+
ModelAndView resolved = resolver.resolveException(this.request, this.response,
87+
null, new HttpRequestMethodNotSupportedException("POST"));
88+
assertThat(resolved.getViewName()).isEqualTo("test-view");
89+
}
90+
91+
private AnnotationConfigWebApplicationContext getParentApplicationContext() {
92+
AnnotationConfigWebApplicationContext parent = new AnnotationConfigWebApplicationContext();
93+
parent.refresh();
94+
return parent;
95+
}
96+
97+
@Configuration
98+
@Import(EndpointWebMvcChildContextConfiguration.class)
99+
@EnableConfigurationProperties(ManagementServerProperties.class)
100+
static class BaseConfiguration {
101+
102+
}
103+
104+
@Configuration
105+
@Import(BaseConfiguration.class)
106+
static class HandlerExceptionResolverConfiguration {
107+
108+
@Bean
109+
public HandlerExceptionResolver testResolver() {
110+
return new TestHandlerExceptionResolver();
111+
}
112+
113+
}
114+
115+
static class TestHandlerExceptionResolver implements HandlerExceptionResolver {
116+
117+
@Override
118+
public ModelAndView resolveException(HttpServletRequest request,
119+
HttpServletResponse response, Object handler, Exception ex) {
120+
return new ModelAndView("test-view");
121+
}
122+
123+
}
124+
125+
}

0 commit comments

Comments
 (0)