Skip to content

Commit e18901d

Browse files
committed
Headers support in ResponseStatusExceptionResolver
Closes gh-24944
1 parent 8265db0 commit e18901d

File tree

2 files changed

+26
-4
lines changed

2 files changed

+26
-4
lines changed

spring-webmvc/src/main/java/org/springframework/web/servlet/mvc/annotation/ResponseStatusExceptionResolver.java

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2002-2018 the original author or authors.
2+
* Copyright 2002-2020 the original author or authors.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -115,8 +115,10 @@ protected ModelAndView resolveResponseStatus(ResponseStatus responseStatus, Http
115115

116116
/**
117117
* Template method that handles an {@link ResponseStatusException}.
118-
* <p>The default implementation delegates to {@link #applyStatusAndReason}
119-
* with the status code and reason from the exception.
118+
* <p>The default implementation applies the headers from
119+
* {@link ResponseStatusException#getResponseHeaders()} and delegates to
120+
* {@link #applyStatusAndReason} with the status code and reason from the
121+
* exception.
120122
* @param ex the exception
121123
* @param request current HTTP request
122124
* @param response current HTTP response
@@ -128,6 +130,12 @@ protected ModelAndView resolveResponseStatus(ResponseStatus responseStatus, Http
128130
protected ModelAndView resolveResponseStatusException(ResponseStatusException ex,
129131
HttpServletRequest request, HttpServletResponse response, @Nullable Object handler) throws Exception {
130132

133+
ex.getResponseHeaders().forEach((name, values) -> {
134+
if (response.getHeader(name) == null) {
135+
values.forEach(value -> response.addHeader(name, value));
136+
}
137+
});
138+
131139
int statusCode = ex.getStatus().value();
132140
String reason = ex.getReason();
133141
return applyStatusAndReason(statusCode, reason, response);

spring-webmvc/src/test/java/org/springframework/web/servlet/mvc/annotation/ResponseStatusExceptionResolverTests.java

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2002-2019 the original author or authors.
2+
* Copyright 2002-2020 the original author or authors.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -18,6 +18,7 @@
1818

1919
import java.lang.annotation.Retention;
2020
import java.lang.annotation.RetentionPolicy;
21+
import java.util.Arrays;
2122
import java.util.Locale;
2223

2324
import org.junit.jupiter.api.BeforeEach;
@@ -28,8 +29,11 @@
2829
import org.springframework.context.i18n.LocaleContextHolder;
2930
import org.springframework.context.support.StaticMessageSource;
3031
import org.springframework.core.annotation.AliasFor;
32+
import org.springframework.http.HttpHeaders;
33+
import org.springframework.http.HttpMethod;
3134
import org.springframework.http.HttpStatus;
3235
import org.springframework.web.bind.annotation.ResponseStatus;
36+
import org.springframework.web.server.MethodNotAllowedException;
3337
import org.springframework.web.server.ResponseStatusException;
3438
import org.springframework.web.servlet.ModelAndView;
3539
import org.springframework.web.testfixture.servlet.MockHttpServletRequest;
@@ -128,6 +132,16 @@ public void responseStatusExceptionWithReason() throws Exception {
128132
assertResolved(mav, 400, "The reason");
129133
}
130134

135+
@Test
136+
void responseStatusExceptionWithHeaders() {
137+
Exception ex = new MethodNotAllowedException(
138+
HttpMethod.GET, Arrays.asList(HttpMethod.POST, HttpMethod.PUT));
139+
140+
ModelAndView mav = exceptionResolver.resolveException(request, response, null, ex);
141+
142+
assertResolved(mav, 405, "Request method 'GET' not supported");
143+
assertThat(response.getHeader(HttpHeaders.ALLOW)).isEqualTo("POST,PUT");
144+
}
131145

132146
private void assertResolved(ModelAndView mav, int status, String reason) {
133147
assertThat(mav != null && mav.isEmpty()).as("No Empty ModelAndView returned").isTrue();

0 commit comments

Comments
 (0)