Skip to content

Commit fdd4078

Browse files
Fix HttpMessageNotWritableException for UUID to string
1 parent b167068 commit fdd4078

File tree

1 file changed

+98
-0
lines changed

1 file changed

+98
-0
lines changed
Lines changed: 98 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,98 @@
1+
package org.gridsuite.shortcircuit.server.converter;
2+
3+
import lombok.NonNull;
4+
import org.jetbrains.annotations.NotNull;
5+
import org.springframework.boot.context.properties.bind.Binder;
6+
import org.springframework.boot.web.servlet.server.Encoding;
7+
import org.springframework.core.env.Environment;
8+
import org.springframework.http.HttpHeaders;
9+
import org.springframework.http.HttpInputMessage;
10+
import org.springframework.http.HttpOutputMessage;
11+
import org.springframework.http.MediaType;
12+
import org.springframework.http.converter.AbstractHttpMessageConverter;
13+
import org.springframework.http.converter.HttpMessageConverter;
14+
import org.springframework.http.converter.HttpMessageNotReadableException;
15+
import org.springframework.http.converter.HttpMessageNotWritableException;
16+
import org.springframework.lang.Nullable;
17+
import org.springframework.stereotype.Component;
18+
import org.springframework.util.MimeType;
19+
import org.springframework.util.StreamUtils;
20+
21+
import java.io.IOException;
22+
import java.nio.charset.Charset;
23+
import java.nio.charset.StandardCharsets;
24+
import java.util.List;
25+
import java.util.Objects;
26+
import java.util.Optional;
27+
import java.util.UUID;
28+
29+
/**
30+
* Implementation of {@link HttpMessageConverter} that can read and write {@link UUID} to/from strings.
31+
*
32+
* @since 2.0
33+
*/
34+
@Component
35+
public class UuidHttpConverter extends AbstractHttpMessageConverter<UUID> {
36+
private final Encoding encoding;
37+
private final List<Charset> availableCharsets = List.copyOf(Charset.availableCharsets().values());
38+
39+
protected UuidHttpConverter(@NonNull final Environment environment) {
40+
super(StandardCharsets.UTF_8, MediaType.TEXT_PLAIN);
41+
encoding = Binder.get(environment).bindOrCreate("server.servlet.encoding", Encoding.class);
42+
}
43+
44+
/**
45+
* {@inheritDoc}
46+
*/
47+
@Override
48+
@NotNull
49+
public Charset getDefaultCharset() {
50+
return Objects.requireNonNullElse(encoding.getCharset(), super.getDefaultCharset());
51+
}
52+
53+
/**
54+
* {@inheritDoc}
55+
*/
56+
@Override
57+
protected boolean supports(final Class<?> clazz) {
58+
return UUID.class == clazz;
59+
}
60+
61+
/**
62+
* {@inheritDoc}
63+
*/
64+
@Override
65+
@NotNull
66+
protected Long getContentLength(UUID uuid, MediaType contentType) throws IOException {
67+
return (long) uuid.toString().getBytes(getContentTypeCharset(contentType)).length;
68+
69+
}
70+
71+
/**
72+
* {@inheritDoc}
73+
*/
74+
@Override
75+
@NotNull
76+
protected UUID readInternal(final Class<? extends UUID> clazz, final HttpInputMessage inputMessage) throws IOException, HttpMessageNotReadableException {
77+
return UUID.fromString(StreamUtils.copyToString(inputMessage.getBody(), getContentTypeCharset(inputMessage.getHeaders().getContentType())));
78+
}
79+
80+
/**
81+
* {@inheritDoc}
82+
*/
83+
@Override
84+
protected void writeInternal(final UUID uuid, final HttpOutputMessage outputMessage) throws IOException, HttpMessageNotWritableException {
85+
final HttpHeaders headers = outputMessage.getHeaders();
86+
if (headers.get(HttpHeaders.ACCEPT_CHARSET) == null) {
87+
headers.setAcceptCharset(this.availableCharsets);
88+
}
89+
StreamUtils.copy(uuid.toString(), this.getContentTypeCharset(headers.getContentType()), outputMessage.getBody());
90+
}
91+
92+
@NotNull
93+
private Charset getContentTypeCharset(@Nullable final MediaType contentType) {
94+
return Objects.requireNonNull(Optional.ofNullable(contentType)
95+
.map(MimeType::getCharset)
96+
.orElseGet(this::getDefaultCharset), "No default charset");
97+
}
98+
}

0 commit comments

Comments
 (0)