Polishing

This commit is contained in:
Juergen Hoeller
2026-08-11 23:48:56 +02:00
parent cc751e61a2
commit 00b9063e7d
10 changed files with 80 additions and 81 deletions
@@ -50,11 +50,6 @@ public class ByteArrayHttpMessageConverter extends AbstractHttpMessageConverter<
return byte[].class == clazz;
}
@Override
public boolean canWriteRepeatedly(byte[] bytes, @Nullable MediaType contentType) {
return true;
}
@Override
public byte[] readInternal(Class<? extends byte[]> clazz, HttpInputMessage message) throws IOException {
long length = message.getHeaders().getContentLength();
@@ -72,6 +67,11 @@ public class ByteArrayHttpMessageConverter extends AbstractHttpMessageConverter<
outputMessage.getBody().write(bytes);
}
@Override
public boolean canWriteRepeatedly(byte[] bytes, @Nullable MediaType contentType) {
return true;
}
@Override
@SuppressWarnings("removal")
protected boolean supportsRepeatableWrites(byte[] bytes) {
@@ -56,6 +56,24 @@ public interface HttpMessageConverter<T> {
*/
boolean canWrite(Class<?> clazz, @Nullable MediaType mediaType);
/**
* Indicates whether this message converter can
* {@linkplain #write(Object, MediaType, HttpOutputMessage) write} the
* given payload multiple times.
* <p>This can be used by HTTP client libraries to know whether a message can be
* sent again, for example after an HTTP redirect. The default implementation
* returns {@code false}. This typically returns false if the payload can be read
* only once.
* @param t the object t
* @param contentType the content type to use when writing.
* @return {@code true} if {@code t} can be written repeatedly;
* {@code false} otherwise
* @since 7.1
*/
default boolean canWriteRepeatedly(T t, @Nullable MediaType contentType) {
return false;
}
/**
* Return the list of media types supported by this converter. The list may
* not apply to every possible target element type and calls to this method
@@ -108,22 +126,4 @@ public interface HttpMessageConverter<T> {
void write(T t, @Nullable MediaType contentType, HttpOutputMessage outputMessage)
throws IOException, HttpMessageNotWritableException;
/**
* Indicates whether this message converter can
* {@linkplain #write(Object, MediaType, HttpOutputMessage) write} the
* given payload multiple times.
* <p>This can be used by HTTP client libraries to know whether a message can be
* sent again, for example after an HTTP redirect. The default implementation
* returns {@code false}. This typically returns false if the payload can be read
* only once.
* @param t the object t
* @param contentType the content type to use when writing.
* @return {@code true} if {@code t} can be written repeatedly;
* {@code false} otherwise
* @since 7.1
*/
default boolean canWriteRepeatedly(T t, @Nullable MediaType contentType) {
return false;
}
}
@@ -71,11 +71,6 @@ public class ResourceHttpMessageConverter extends AbstractHttpMessageConverter<R
}
@Override
public boolean canWriteRepeatedly(Resource resource, @Nullable MediaType contentType) {
return !(resource instanceof InputStreamResource);
}
@Override
protected boolean supports(Class<?> clazz) {
return Resource.class.isAssignableFrom(clazz);
@@ -145,6 +140,11 @@ public class ResourceHttpMessageConverter extends AbstractHttpMessageConverter<R
return (contentLength < 0 ? null : contentLength);
}
@Override
public boolean canWriteRepeatedly(Resource resource, @Nullable MediaType contentType) {
return !(resource instanceof InputStreamResource);
}
@Override
@SuppressWarnings("removal")
protected boolean supportsRepeatableWrites(Resource resource) {
@@ -121,6 +121,16 @@ public class ResourceRegionHttpMessageConverter extends AbstractGenericHttpMessa
}
}
@Override
@SuppressWarnings("removal")
protected boolean supportsRepeatableWrites(Object object) {
return canWriteRepeatedly(object, null);
}
private boolean supportsRepeatableWrites(ResourceRegion region) {
return !(region.getResource() instanceof InputStreamResource);
}
@Override
protected void writeInternal(Object object, @Nullable Type type, HttpOutputMessage outputMessage)
throws IOException, HttpMessageNotWritableException {
@@ -156,16 +166,6 @@ public class ResourceRegionHttpMessageConverter extends AbstractGenericHttpMessa
return MediaTypeFactory.getMediaType(resource).orElse(MediaType.APPLICATION_OCTET_STREAM);
}
@Override
@SuppressWarnings("removal")
protected boolean supportsRepeatableWrites(Object object) {
return canWriteRepeatedly(object, null);
}
private boolean supportsRepeatableWrites(ResourceRegion region) {
return !(region.getResource() instanceof InputStreamResource);
}
protected void writeResourceRegion(ResourceRegion region, HttpOutputMessage outputMessage) throws IOException {
Assert.notNull(region, "ResourceRegion must not be null");
@@ -89,11 +89,6 @@ public class StringHttpMessageConverter extends AbstractHttpMessageConverter<Str
return String.class == clazz;
}
@Override
public boolean canWriteRepeatedly(String s, @Nullable MediaType contentType) {
return true;
}
@Override
protected String readInternal(Class<? extends String> clazz, HttpInputMessage inputMessage) throws IOException {
Charset charset = getContentTypeCharset(inputMessage.getHeaders().getContentType());
@@ -104,12 +99,15 @@ public class StringHttpMessageConverter extends AbstractHttpMessageConverter<Str
}
@Override
protected Long getContentLength(String str, @Nullable MediaType contentType) {
Charset charset = getContentTypeCharset(contentType);
return (long) str.getBytes(charset).length;
protected void writeInternal(String str, HttpOutputMessage outputMessage) throws IOException {
HttpHeaders headers = outputMessage.getHeaders();
if (this.writeAcceptCharset && headers.get(HttpHeaders.ACCEPT_CHARSET) == null) {
headers.setAcceptCharset(getAcceptedCharsets());
}
Charset charset = getContentTypeCharset(headers.getContentType());
outputMessage.getBody().write(str.getBytes(charset));
}
@Override
protected void addDefaultHeaders(HttpHeaders headers, String s, @Nullable MediaType type) throws IOException {
if (headers.getContentType() == null ) {
@@ -123,16 +121,11 @@ public class StringHttpMessageConverter extends AbstractHttpMessageConverter<Str
}
@Override
protected void writeInternal(String str, HttpOutputMessage outputMessage) throws IOException {
HttpHeaders headers = outputMessage.getHeaders();
if (this.writeAcceptCharset && headers.get(HttpHeaders.ACCEPT_CHARSET) == null) {
headers.setAcceptCharset(getAcceptedCharsets());
}
Charset charset = getContentTypeCharset(headers.getContentType());
outputMessage.getBody().write(str.getBytes(charset));
protected Long getContentLength(String str, @Nullable MediaType contentType) {
Charset charset = getContentTypeCharset(contentType);
return (long) str.getBytes(charset).length;
}
/**
* Return the list of supported {@link Charset Charsets}.
* <p>By default, returns {@link Charset#availableCharsets()}.
@@ -165,6 +158,11 @@ public class StringHttpMessageConverter extends AbstractHttpMessageConverter<Str
return charset;
}
@Override
public boolean canWriteRepeatedly(String s, @Nullable MediaType contentType) {
return true;
}
@Override
@SuppressWarnings("removal")
protected boolean supportsRepeatableWrites(String s) {
@@ -67,11 +67,6 @@ public abstract class AbstractWireFeedHttpMessageConverter<T extends WireFeed>
}
@Override
public boolean canWriteRepeatedly(T t, @Nullable MediaType contentType) {
return true;
}
@Override
@SuppressWarnings("unchecked")
protected T readInternal(Class<? extends T> clazz, HttpInputMessage inputMessage)
@@ -113,6 +108,11 @@ public abstract class AbstractWireFeedHttpMessageConverter<T extends WireFeed>
}
}
@Override
public boolean canWriteRepeatedly(T t, @Nullable MediaType contentType) {
return true;
}
@Override
@SuppressWarnings("removal")
protected boolean supportsRepeatableWrites(T t) {
@@ -87,10 +87,6 @@ public class GsonHttpMessageConverter extends AbstractJsonHttpMessageConverter {
return this.gson;
}
@Override
public boolean canWriteRepeatedly(Object o, @Nullable MediaType contentType) {
return true;
}
@Override
protected Object readInternal(Type resolvedType, Reader reader) throws Exception {
@@ -112,6 +108,11 @@ public class GsonHttpMessageConverter extends AbstractJsonHttpMessageConverter {
}
}
@Override
public boolean canWriteRepeatedly(Object o, @Nullable MediaType contentType) {
return true;
}
@Override
@SuppressWarnings("removal")
protected boolean supportsRepeatableWrites(Object o) {
@@ -96,10 +96,6 @@ public class JsonbHttpMessageConverter extends AbstractJsonHttpMessageConverter
return this.jsonb;
}
@Override
public boolean canWriteRepeatedly(Object o, @Nullable MediaType contentType) {
return true;
}
@Override
protected Object readInternal(Type resolvedType, Reader reader) throws Exception {
@@ -116,6 +112,11 @@ public class JsonbHttpMessageConverter extends AbstractJsonHttpMessageConverter
}
}
@Override
public boolean canWriteRepeatedly(Object o, @Nullable MediaType contentType) {
return true;
}
@Override
@SuppressWarnings("removal")
protected boolean supportsRepeatableWrites(Object o) {
@@ -98,13 +98,13 @@ public class ProtobufHttpMessageConverter extends AbstractHttpMessageConverter<M
private static final boolean PROTOBUF_JSON_FORMAT_PRESENT =
ClassUtils.isPresent("com.google.protobuf.util.JsonFormat", ProtobufHttpMessageConverter.class.getClassLoader());
private static final Map<Class<?>, Method> methodCache = new ConcurrentReferenceHashMap<>();
private final ProtobufHttpMessageConverter.@Nullable ProtobufFormatDelegate protobufFormatDelegate;
final ExtensionRegistry extensionRegistry;
private final ProtobufHttpMessageConverter.@Nullable ProtobufFormatDelegate protobufFormatDelegate;
/**
* Construct a new {@code ProtobufHttpMessageConverter}.
@@ -122,12 +122,6 @@ public class ProtobufHttpMessageConverter extends AbstractHttpMessageConverter<M
this(null, extensionRegistry);
}
@Override
public boolean canWriteRepeatedly(Message message, @Nullable MediaType contentType) {
return true;
}
/**
* Constructor for a subclass that supports additional formats.
* @param formatDelegate delegate to read and write additional formats
@@ -260,6 +254,11 @@ public class ProtobufHttpMessageConverter extends AbstractHttpMessageConverter<M
response.getHeaders().set(X_PROTOBUF_MESSAGE_HEADER, message.getDescriptorForType().getFullName());
}
@Override
public boolean canWriteRepeatedly(Message message, @Nullable MediaType contentType) {
return true;
}
@Override
@SuppressWarnings("removal")
protected boolean supportsRepeatableWrites(Message message) {
@@ -148,11 +148,6 @@ public class SourceHttpMessageConverter<T extends Source> extends AbstractHttpMe
return SUPPORTED_CLASSES.contains(clazz);
}
@Override
public boolean canWriteRepeatedly(T t, @Nullable MediaType contentType) {
return t instanceof DOMSource;
}
@Override
@SuppressWarnings("unchecked")
protected T readInternal(Class<? extends T> clazz, HttpInputMessage inputMessage)
@@ -325,6 +320,11 @@ public class SourceHttpMessageConverter<T extends Source> extends AbstractHttpMe
this.transformerFactory.newTransformer().transform(source, result);
}
@Override
public boolean canWriteRepeatedly(T t, @Nullable MediaType contentType) {
return (t instanceof DOMSource);
}
@Override
@SuppressWarnings("removal")
protected boolean supportsRepeatableWrites(T t) {