Closed
Description
Affects: Spring Framework 5.2.5.RELEASE
When throwing a derived exception like:
public class NotModifiedStatusException extends ResponseStatusException {
private static final long serialVersionUID = -4380761922076567306L;
private String etag;
public NotModifiedStatusException(String etag) {
super(HttpStatus.NOT_MODIFIED);
this.etag = etag;
}
@Override
public Map<String, String> getHeaders() {
return getResponseHeaders().toSingleValueMap();
}
@Override
public HttpHeaders getResponseHeaders() {
HttpHeaders headers = new HttpHeaders();
headers.setETag(etag);
return headers;
}
}
the headers are completely ignored:
17:56:01,681 [http-nio-127.0.0.1-8081-exec-5] DEBUG o.s.w.s.m.a.ResponseStatusExceptionResolver: Resolved [...NotModifiedStatusException: 304 NOT_MODIFIED]
17:56:01,681 [http-nio-127.0.0.1-8081-exec-5] TRACE o.s.web.servlet.DispatcherServlet: No view rendering, null ModelAndView returned.
17:56:01,681 [http-nio-127.0.0.1-8081-exec-5] DEBUG o.s.web.servlet.DispatcherServlet: Completed 304 NOT_MODIFIED, headers={}
It happily ignores the headers:
My naive solution seems to work:
@Component
public class HeaderAwareResponseStatusExceptionResolver extends ResponseStatusExceptionResolver {
@Override
public int getOrder() {
return super.getOrder() + 1;
}
@Override
protected ModelAndView resolveResponseStatusException(ResponseStatusException ex,
HttpServletRequest request, HttpServletResponse response, Object handler)
throws Exception {
int statusCode = ex.getStatus().value();
String reason = ex.getReason();
HttpHeaders headers = ex.getResponseHeaders();
headers.forEach((name, values) -> values.forEach(value -> response.addHeader(name, value)));
if (!StringUtils.hasLength(reason)) {
response.sendError(statusCode);
} else {
response.sendError(statusCode, reason);
}
return new ModelAndView();
}
}