From e0d6b691952ff3be7765294bad96ece14578dcea Mon Sep 17 00:00:00 2001 From: rstoyanchev Date: Thu, 4 Jan 2024 14:53:13 +0000 Subject: [PATCH] Update contribution Closes gh-30300 --- .../springframework/web/ErrorResponse.java | 9 ------- .../web/server/ResponseStatusException.java | 22 +++++++++++++++- .../web/ErrorResponseExceptionTests.java | 26 ++++++++++++++++++- .../ResponseEntityExceptionHandlerTests.java | 10 +++---- 4 files changed, 51 insertions(+), 16 deletions(-) diff --git a/spring-web/src/main/java/org/springframework/web/ErrorResponse.java b/spring-web/src/main/java/org/springframework/web/ErrorResponse.java index dfc545bb2daa..c83bcdb1c4b8 100644 --- a/spring-web/src/main/java/org/springframework/web/ErrorResponse.java +++ b/spring-web/src/main/java/org/springframework/web/ErrorResponse.java @@ -40,7 +40,6 @@ * {@code @RestController} or {@code RestControllerAdvice} class. * * @author Rossen Stoyanchev - * @author Yanming Zhou * @since 6.0 * @see ErrorResponseException */ @@ -143,14 +142,6 @@ default ProblemDetail updateAndGetBody(@Nullable MessageSource messageSource, Lo if (detail != null) { getBody().setDetail(detail); } - else { - // detail from ResponseStatusException reason may be message code - detail = getBody().getDetail(); - if (detail != null) { - detail = messageSource.getMessage(detail, null, detail, locale); - getBody().setDetail(detail); - } - } String title = messageSource.getMessage(getTitleMessageCode(), null, null, locale); if (title != null) { getBody().setTitle(title); diff --git a/spring-web/src/main/java/org/springframework/web/server/ResponseStatusException.java b/spring-web/src/main/java/org/springframework/web/server/ResponseStatusException.java index c779133e5e69..8e9c039aae71 100644 --- a/spring-web/src/main/java/org/springframework/web/server/ResponseStatusException.java +++ b/spring-web/src/main/java/org/springframework/web/server/ResponseStatusException.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2022 the original author or authors. + * Copyright 2002-2024 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. @@ -16,6 +16,9 @@ package org.springframework.web.server; +import java.util.Locale; + +import org.springframework.context.MessageSource; import org.springframework.http.HttpHeaders; import org.springframework.http.HttpStatusCode; import org.springframework.http.ProblemDetail; @@ -127,6 +130,23 @@ public HttpHeaders getResponseHeaders() { return HttpHeaders.EMPTY; } + @Override + public ProblemDetail updateAndGetBody(@Nullable MessageSource messageSource, Locale locale) { + super.updateAndGetBody(messageSource, locale); + + // The reason may be a code (consistent with ResponseStatusExceptionResolver) + + if (messageSource != null && getReason() != null && getReason().equals(getBody().getDetail())) { + Object[] arguments = getDetailMessageArguments(messageSource, locale); + String resolved = messageSource.getMessage(getReason(), arguments, null, locale); + if (resolved != null) { + getBody().setDetail(resolved); + } + } + + return getBody(); + } + @Override public String getMessage() { return getStatusCode() + (this.reason != null ? " \"" + this.reason + "\"" : ""); diff --git a/spring-web/src/test/java/org/springframework/web/ErrorResponseExceptionTests.java b/spring-web/src/test/java/org/springframework/web/ErrorResponseExceptionTests.java index 1427aa964b04..6405a092cd1d 100644 --- a/spring-web/src/test/java/org/springframework/web/ErrorResponseExceptionTests.java +++ b/spring-web/src/test/java/org/springframework/web/ErrorResponseExceptionTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2023 the original author or authors. + * Copyright 2002-2024 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.springframework.beans.testfixture.beans.TestBean; import org.springframework.context.MessageSourceResolvable; +import org.springframework.context.i18n.LocaleContextHolder; import org.springframework.context.support.StaticMessageSource; import org.springframework.core.MethodParameter; import org.springframework.http.HttpHeaders; @@ -51,6 +52,7 @@ import org.springframework.web.server.MethodNotAllowedException; import org.springframework.web.server.MissingRequestValueException; import org.springframework.web.server.NotAcceptableStatusException; +import org.springframework.web.server.ResponseStatusException; import org.springframework.web.server.ServerErrorException; import org.springframework.web.server.UnsatisfiedRequestParameterException; import org.springframework.web.server.UnsupportedMediaTypeStatusException; @@ -415,6 +417,28 @@ void methodNotAllowedExceptionWithoutSupportedMethods() { assertThat(ex.getHeaders()).isEmpty(); } + @Test // gh-30300 + void responseStatusException() { + + Locale locale = Locale.UK; + LocaleContextHolder.setLocale(locale); + + try { + String reason = "bad.request"; + String message = "Breaking Bad Request"; + StaticMessageSource messageSource = new StaticMessageSource(); + messageSource.addMessage(reason, locale, message); + + ResponseStatusException ex = new ResponseStatusException(HttpStatus.BAD_REQUEST, reason); + + ProblemDetail problemDetail = ex.updateAndGetBody(messageSource, locale); + assertThat(problemDetail.getDetail()).isEqualTo(message); + } + finally { + LocaleContextHolder.resetLocaleContext(); + } + } + private void assertStatus(ErrorResponse ex, HttpStatus status) { ProblemDetail body = ex.getBody(); assertThat(ex.getStatusCode()).isEqualTo(status); diff --git a/spring-webmvc/src/test/java/org/springframework/web/servlet/mvc/method/annotation/ResponseEntityExceptionHandlerTests.java b/spring-webmvc/src/test/java/org/springframework/web/servlet/mvc/method/annotation/ResponseEntityExceptionHandlerTests.java index bee3c569e407..94dcc038e72b 100644 --- a/spring-webmvc/src/test/java/org/springframework/web/servlet/mvc/method/annotation/ResponseEntityExceptionHandlerTests.java +++ b/spring-webmvc/src/test/java/org/springframework/web/servlet/mvc/method/annotation/ResponseEntityExceptionHandlerTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2023 the original author or authors. + * Copyright 2002-2024 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. @@ -201,21 +201,21 @@ public void errorResponseProblemDetailViaMessageSource() { } } - @Test + @Test // gh-30300 public void reasonAsDetailShouldBeUpdatedViaMessageSource() { Locale locale = Locale.UK; LocaleContextHolder.setLocale(locale); - String code = "bad.request"; + String reason = "bad.request"; String message = "Breaking Bad Request"; try { StaticMessageSource messageSource = new StaticMessageSource(); - messageSource.addMessage(code, locale, message); + messageSource.addMessage(reason, locale, message); this.exceptionHandler.setMessageSource(messageSource); - ResponseEntity entity = testException(new ResponseStatusException(HttpStatus.BAD_REQUEST, code)); + ResponseEntity entity = testException(new ResponseStatusException(HttpStatus.BAD_REQUEST, reason)); ProblemDetail body = (ProblemDetail) entity.getBody(); assertThat(body.getDetail()).isEqualTo(message);