Update contribution

Closes gh-30300
This commit is contained in:
rstoyanchev 2024-01-04 14:53:13 +00:00
parent a3532bfccc
commit e0d6b69195
4 changed files with 51 additions and 16 deletions

View File

@ -40,7 +40,6 @@ import org.springframework.lang.Nullable;
* {@code @RestController} or {@code RestControllerAdvice} class. * {@code @RestController} or {@code RestControllerAdvice} class.
* *
* @author Rossen Stoyanchev * @author Rossen Stoyanchev
* @author Yanming Zhou
* @since 6.0 * @since 6.0
* @see ErrorResponseException * @see ErrorResponseException
*/ */
@ -143,14 +142,6 @@ public interface ErrorResponse {
if (detail != null) { if (detail != null) {
getBody().setDetail(detail); 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); String title = messageSource.getMessage(getTitleMessageCode(), null, null, locale);
if (title != null) { if (title != null) {
getBody().setTitle(title); getBody().setTitle(title);

View File

@ -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"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
@ -16,6 +16,9 @@
package org.springframework.web.server; package org.springframework.web.server;
import java.util.Locale;
import org.springframework.context.MessageSource;
import org.springframework.http.HttpHeaders; import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatusCode; import org.springframework.http.HttpStatusCode;
import org.springframework.http.ProblemDetail; import org.springframework.http.ProblemDetail;
@ -127,6 +130,23 @@ public class ResponseStatusException extends ErrorResponseException {
return HttpHeaders.EMPTY; 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 @Override
public String getMessage() { public String getMessage() {
return getStatusCode() + (this.reason != null ? " \"" + this.reason + "\"" : ""); return getStatusCode() + (this.reason != null ? " \"" + this.reason + "\"" : "");

View File

@ -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"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
@ -25,6 +25,7 @@ import org.junit.jupiter.api.Test;
import org.springframework.beans.testfixture.beans.TestBean; import org.springframework.beans.testfixture.beans.TestBean;
import org.springframework.context.MessageSourceResolvable; import org.springframework.context.MessageSourceResolvable;
import org.springframework.context.i18n.LocaleContextHolder;
import org.springframework.context.support.StaticMessageSource; import org.springframework.context.support.StaticMessageSource;
import org.springframework.core.MethodParameter; import org.springframework.core.MethodParameter;
import org.springframework.http.HttpHeaders; import org.springframework.http.HttpHeaders;
@ -51,6 +52,7 @@ import org.springframework.web.multipart.support.MissingServletRequestPartExcept
import org.springframework.web.server.MethodNotAllowedException; import org.springframework.web.server.MethodNotAllowedException;
import org.springframework.web.server.MissingRequestValueException; import org.springframework.web.server.MissingRequestValueException;
import org.springframework.web.server.NotAcceptableStatusException; import org.springframework.web.server.NotAcceptableStatusException;
import org.springframework.web.server.ResponseStatusException;
import org.springframework.web.server.ServerErrorException; import org.springframework.web.server.ServerErrorException;
import org.springframework.web.server.UnsatisfiedRequestParameterException; import org.springframework.web.server.UnsatisfiedRequestParameterException;
import org.springframework.web.server.UnsupportedMediaTypeStatusException; import org.springframework.web.server.UnsupportedMediaTypeStatusException;
@ -415,6 +417,28 @@ public class ErrorResponseExceptionTests {
assertThat(ex.getHeaders()).isEmpty(); 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) { private void assertStatus(ErrorResponse ex, HttpStatus status) {
ProblemDetail body = ex.getBody(); ProblemDetail body = ex.getBody();
assertThat(ex.getStatusCode()).isEqualTo(status); assertThat(ex.getStatusCode()).isEqualTo(status);

View File

@ -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"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
@ -201,21 +201,21 @@ public class ResponseEntityExceptionHandlerTests {
} }
} }
@Test @Test // gh-30300
public void reasonAsDetailShouldBeUpdatedViaMessageSource() { public void reasonAsDetailShouldBeUpdatedViaMessageSource() {
Locale locale = Locale.UK; Locale locale = Locale.UK;
LocaleContextHolder.setLocale(locale); LocaleContextHolder.setLocale(locale);
String code = "bad.request"; String reason = "bad.request";
String message = "Breaking Bad Request"; String message = "Breaking Bad Request";
try { try {
StaticMessageSource messageSource = new StaticMessageSource(); StaticMessageSource messageSource = new StaticMessageSource();
messageSource.addMessage(code, locale, message); messageSource.addMessage(reason, locale, message);
this.exceptionHandler.setMessageSource(messageSource); 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(); ProblemDetail body = (ProblemDetail) entity.getBody();
assertThat(body.getDetail()).isEqualTo(message); assertThat(body.getDetail()).isEqualTo(message);