Skip to content

ResponseStatusExceptionResolver ignores ResponseStatusException headers #24944

Closed
@michael-o

Description

@michael-o

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:

protected ModelAndView resolveResponseStatusException(ResponseStatusException ex,
HttpServletRequest request, HttpServletResponse response, @Nullable Object handler) throws Exception {
int statusCode = ex.getStatus().value();
String reason = ex.getReason();
return applyStatusAndReason(statusCode, reason, response);

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();
	}

}

Metadata

Metadata

Assignees

Labels

in: webIssues in web modules (web, webmvc, webflux, websocket)type: enhancementA general enhancement

Type

No type

Projects

No projects

Milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions