Avoid setCharacterEncoding(Charset) call with null value

Includes consistent content length check for functional response.

See gh-36343
This commit is contained in:
Juergen Hoeller
2026-02-17 18:56:59 +01:00
parent a9f447e8d7
commit 727ccd04ef
3 changed files with 22 additions and 7 deletions
@@ -18,6 +18,7 @@ package org.springframework.http.server;
import java.io.IOException;
import java.io.OutputStream;
import java.nio.charset.Charset;
import jakarta.servlet.http.HttpServletResponse;
import org.jspecify.annotations.Nullable;
@@ -116,15 +117,18 @@ public class ServletServerHttpResponse implements ServerHttpResponse {
// Lazy parsing into MediaType
MediaType contentType = this.headers.getContentType();
if (contentType != null) {
this.servletResponse.setCharacterEncoding(contentType.getCharset());
Charset charset = contentType.getCharset();
if (charset != null) {
this.servletResponse.setCharacterEncoding(charset);
}
}
}
catch (Exception ex) {
// Leave character encoding unspecified
}
}
this.headersWritten = true;
}
this.headersWritten = true;
}
}
@@ -18,6 +18,7 @@ package org.springframework.http.server.reactive;
import java.io.IOException;
import java.nio.ByteBuffer;
import java.nio.charset.Charset;
import jakarta.servlet.AsyncContext;
import jakarta.servlet.AsyncEvent;
@@ -122,25 +123,26 @@ class ServletServerHttpResponse extends AbstractListenerServerHttpResponse {
protected void adaptHeaders(boolean removeAdaptedHeaders) {
HttpHeaders headers = getHeaders();
// HttpServletResponse exposes some headers as properties: we should include those if not already present
// HttpServletResponse exposes some headers as properties: we should include those if not already present
if (this.response.getContentType() == null && headers.containsHeader(HttpHeaders.CONTENT_TYPE)) {
this.response.setContentType(headers.getFirst(HttpHeaders.CONTENT_TYPE));
}
if (this.response.getCharacterEncoding() == null && headers.containsHeader(HttpHeaders.CONTENT_TYPE)) {
try {
// Lazy parsing into MediaType
MediaType contentType = headers.getContentType();
if (contentType != null) {
this.response.setCharacterEncoding(contentType.getCharset());
Charset charset = contentType.getCharset();
if (charset != null) {
this.response.setCharacterEncoding(charset);
}
}
}
catch (Exception ex) {
// Leave character encoding unspecified
}
}
long contentLength = headers.getContentLength();
if (contentLength != -1) {
this.response.setContentLengthLong(contentLength);
@@ -17,6 +17,7 @@
package org.springframework.web.servlet.function;
import java.io.IOException;
import java.nio.charset.Charset;
import java.util.Collection;
import java.util.Set;
@@ -61,6 +62,7 @@ abstract class AbstractServerResponse extends ErrorHandlingServerResponse {
this.cookies = CollectionUtils.unmodifiableMultiValueMap(new LinkedMultiValueMap<>(cookies));
}
@Override
public final HttpStatusCode statusCode() {
return this.statusCode;
@@ -121,13 +123,20 @@ abstract class AbstractServerResponse extends ErrorHandlingServerResponse {
// Lazy parsing into MediaType
MediaType contentType = this.headers.getContentType();
if (contentType != null) {
servletResponse.setCharacterEncoding(contentType.getCharset());
Charset charset = contentType.getCharset();
if (charset != null) {
servletResponse.setCharacterEncoding(charset);
}
}
}
catch (Exception ex) {
// Leave character encoding unspecified
}
}
long contentLength = this.headers.getContentLength();
if (contentLength != -1) {
servletResponse.setContentLengthLong(contentLength);
}
}
private void writeCookies(HttpServletResponse servletResponse) {