Skip to content

Commit 8ec9ab6

Browse files
committed
Add builder-based constructors to Jackson 3 infrastructure
This commit also polishes documentation, constructor parameter and field names. Closes gh-35597
1 parent 3493fc9 commit 8ec9ab6

File tree

17 files changed

+325
-119
lines changed

17 files changed

+325
-119
lines changed

spring-jms/src/main/java/org/springframework/jms/support/converter/JacksonJsonMessageConverter.java

Lines changed: 26 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -48,9 +48,6 @@
4848
* {@link #setTargetType targetType} is set to {@link MessageType#TEXT}.
4949
* Converts from a {@link TextMessage} or {@link BytesMessage} to an object.
5050
*
51-
* <p>The default constructor loads {@link tools.jackson.databind.JacksonModule}s
52-
* found by {@link MapperBuilder#findModules(ClassLoader)}.
53-
*
5451
* @author Sebastien Deleuze
5552
* @since 7.0
5653
*/
@@ -62,7 +59,7 @@ public class JacksonJsonMessageConverter implements SmartMessageConverter, BeanC
6259
public static final String DEFAULT_ENCODING = "UTF-8";
6360

6461

65-
private final JsonMapper jsonMapper;
62+
private final JsonMapper mapper;
6663

6764
private MessageType targetType = MessageType.BYTES;
6865

@@ -85,17 +82,27 @@ public class JacksonJsonMessageConverter implements SmartMessageConverter, BeanC
8582
* {@link MapperBuilder#findModules(ClassLoader)}.
8683
*/
8784
public JacksonJsonMessageConverter() {
88-
this.jsonMapper = JsonMapper.builder().findAndAddModules(JacksonJsonMessageConverter.class.getClassLoader()).build();
85+
this(JsonMapper.builder());
86+
}
87+
88+
/**
89+
* Construct a new instance with the provided {@link JsonMapper.Builder}
90+
* customized with the {@link tools.jackson.databind.JacksonModule}s found
91+
* by {@link MapperBuilder#findModules(ClassLoader)}.
92+
* @see JsonMapper#builder()
93+
*/
94+
public JacksonJsonMessageConverter(JsonMapper.Builder builder) {
95+
Assert.notNull(builder, "JsonMapper.Builder must not be null");
96+
this.mapper = builder.findAndAddModules(JacksonJsonMessageConverter.class.getClassLoader()).build();
8997
}
9098

9199
/**
92100
* Construct a new instance with the provided {@link JsonMapper}.
93101
* @see JsonMapper#builder()
94-
* @see MapperBuilder#findModules(ClassLoader)
95102
*/
96-
public JacksonJsonMessageConverter(JsonMapper jsonMapper) {
97-
Assert.notNull(jsonMapper, "JsonMapper must not be null");
98-
this.jsonMapper = jsonMapper;
103+
public JacksonJsonMessageConverter(JsonMapper mapper) {
104+
Assert.notNull(mapper, "JsonMapper must not be null");
105+
this.mapper = mapper;
99106
}
100107

101108
/**
@@ -172,9 +179,9 @@ public Message toMessage(Object object, Session session) throws JMSException, Me
172179
Message message;
173180
try {
174181
message = switch (this.targetType) {
175-
case TEXT -> mapToTextMessage(object, session, this.jsonMapper.writer());
176-
case BYTES -> mapToBytesMessage(object, session, this.jsonMapper.writer());
177-
default -> mapToMessage(object, session, this.jsonMapper.writer(), this.targetType);
182+
case TEXT -> mapToTextMessage(object, session, this.mapper.writer());
183+
case BYTES -> mapToBytesMessage(object, session, this.mapper.writer());
184+
default -> mapToMessage(object, session, this.mapper.writer(), this.targetType);
178185
};
179186
}
180187
catch (IOException ex) {
@@ -205,10 +212,10 @@ public Message toMessage(Object object, Session session, @Nullable Class<?> json
205212
throws JMSException, MessageConversionException {
206213

207214
if (jsonView != null) {
208-
return toMessage(object, session, this.jsonMapper.writerWithView(jsonView));
215+
return toMessage(object, session, this.mapper.writerWithView(jsonView));
209216
}
210217
else {
211-
return toMessage(object, session, this.jsonMapper.writer());
218+
return toMessage(object, session, this.mapper.writer());
212219
}
213220
}
214221

@@ -362,7 +369,7 @@ protected Object convertFromTextMessage(TextMessage message, JavaType targetJava
362369
throws JMSException, IOException {
363370

364371
String body = message.getText();
365-
return this.jsonMapper.readValue(body, targetJavaType);
372+
return this.mapper.readValue(body, targetJavaType);
366373
}
367374

368375
/**
@@ -385,15 +392,15 @@ protected Object convertFromBytesMessage(BytesMessage message, JavaType targetJa
385392
if (encoding != null) {
386393
try {
387394
String body = new String(bytes, encoding);
388-
return this.jsonMapper.readValue(body, targetJavaType);
395+
return this.mapper.readValue(body, targetJavaType);
389396
}
390397
catch (UnsupportedEncodingException ex) {
391398
throw new MessageConversionException("Cannot convert bytes to String", ex);
392399
}
393400
}
394401
else {
395402
// Jackson internally performs encoding detection, falling back to UTF-8.
396-
return this.jsonMapper.readValue(bytes, targetJavaType);
403+
return this.mapper.readValue(bytes, targetJavaType);
397404
}
398405
}
399406

@@ -436,11 +443,11 @@ protected JavaType getJavaTypeForMessage(Message message) throws JMSException {
436443
}
437444
Class<?> mappedClass = this.idClassMappings.get(typeId);
438445
if (mappedClass != null) {
439-
return this.jsonMapper.constructType(mappedClass);
446+
return this.mapper.constructType(mappedClass);
440447
}
441448
try {
442449
Class<?> typeClass = ClassUtils.forName(typeId, this.beanClassLoader);
443-
return this.jsonMapper.constructType(typeClass);
450+
return this.mapper.constructType(typeClass);
444451
}
445452
catch (Throwable ex) {
446453
throw new MessageConversionException("Failed to resolve type id [" + typeId + "]", ex);

spring-messaging/src/main/java/org/springframework/messaging/converter/JacksonJsonMessageConverter.java

Lines changed: 43 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -40,9 +40,6 @@
4040
/**
4141
* A Jackson 3.x based {@link MessageConverter} implementation.
4242
*
43-
* <p>The default constructor loads {@link tools.jackson.databind.JacksonModule}s
44-
* found by {@link MapperBuilder#findModules(ClassLoader)}.
45-
*
4643
* @author Sebastien Deleuze
4744
* @since 7.0
4845
*/
@@ -51,7 +48,7 @@ public class JacksonJsonMessageConverter extends AbstractMessageConverter {
5148
private static final MimeType[] DEFAULT_MIME_TYPES = new MimeType[] {
5249
new MimeType("application", "json"), new MimeType("application", "*+json")};
5350

54-
private final JsonMapper jsonMapper;
51+
private final JsonMapper mapper;
5552

5653

5754
/**
@@ -71,36 +68,58 @@ public JacksonJsonMessageConverter() {
7168
* @param supportedMimeTypes the supported MIME types
7269
*/
7370
public JacksonJsonMessageConverter(MimeType... supportedMimeTypes) {
74-
super(supportedMimeTypes);
75-
this.jsonMapper = JsonMapper.builder().findAndAddModules(JacksonJsonMessageConverter.class.getClassLoader()).build();
71+
this(JsonMapper.builder(), supportedMimeTypes);
7672
}
7773

7874
/**
7975
* Construct a new instance with the provided {@link JsonMapper}.
8076
* @see JsonMapper#builder()
81-
* @see MapperBuilder#findModules(ClassLoader)
8277
*/
83-
public JacksonJsonMessageConverter(JsonMapper jsonMapper) {
84-
this(jsonMapper, DEFAULT_MIME_TYPES);
78+
public JacksonJsonMessageConverter(JsonMapper mapper) {
79+
this(mapper, DEFAULT_MIME_TYPES);
80+
}
81+
82+
83+
/**
84+
* Construct a new instance with the provided {@link JsonMapper.Builder} customized
85+
* with the {@link tools.jackson.databind.JacksonModule}s found
86+
* by {@link MapperBuilder#findModules(ClassLoader)}.
87+
* @see JsonMapper#builder()
88+
*/
89+
public JacksonJsonMessageConverter(JsonMapper.Builder builder) {
90+
this(builder, DEFAULT_MIME_TYPES);
8591
}
8692

8793
/**
8894
* Construct a new instance with the provided {@link JsonMapper} and the
8995
* provided {@link MimeType}s.
9096
* @see JsonMapper#builder()
91-
* @see MapperBuilder#findModules(ClassLoader)
9297
*/
93-
public JacksonJsonMessageConverter(JsonMapper jsonMapper, MimeType... supportedMimeTypes) {
98+
public JacksonJsonMessageConverter(JsonMapper mapper, MimeType... supportedMimeTypes) {
99+
super(supportedMimeTypes);
100+
Assert.notNull(mapper, "JsonMapper must not be null");
101+
this.mapper = mapper;
102+
}
103+
104+
/**
105+
* Construct a new instance with the provided {@link JsonMapper} customized
106+
* with the {@link tools.jackson.databind.JacksonModule}s found by
107+
* {@link MapperBuilder#findModules(ClassLoader)}, and the provided
108+
* {@link MimeType}s.
109+
* @see JsonMapper#builder()
110+
*/
111+
public JacksonJsonMessageConverter(JsonMapper.Builder builder, MimeType... supportedMimeTypes) {
94112
super(supportedMimeTypes);
95-
Assert.notNull(jsonMapper, "JsonMapper must not be null");
96-
this.jsonMapper = jsonMapper;
113+
Assert.notNull(builder, "JsonMapper.Builder must not be null");
114+
this.mapper = builder.findAndAddModules(JacksonJsonMessageConverter.class.getClassLoader()).build();
97115
}
98116

117+
99118
/**
100119
* Return the underlying {@code JsonMapper} for this converter.
101120
*/
102121
protected JsonMapper getJsonMapper() {
103-
return this.jsonMapper;
122+
return this.mapper;
104123
}
105124

106125
@Override
@@ -121,7 +140,7 @@ protected boolean supports(Class<?> clazz) {
121140

122141
@Override
123142
protected @Nullable Object convertFromInternal(Message<?> message, Class<?> targetClass, @Nullable Object conversionHint) {
124-
JavaType javaType = this.jsonMapper.constructType(getResolvedType(targetClass, conversionHint));
143+
JavaType javaType = this.mapper.constructType(getResolvedType(targetClass, conversionHint));
125144
Object payload = message.getPayload();
126145
Class<?> view = getSerializationView(conversionHint);
127146
try {
@@ -130,19 +149,19 @@ protected boolean supports(Class<?> clazz) {
130149
}
131150
else if (payload instanceof byte[] bytes) {
132151
if (view != null) {
133-
return this.jsonMapper.readerWithView(view).forType(javaType).readValue(bytes);
152+
return this.mapper.readerWithView(view).forType(javaType).readValue(bytes);
134153
}
135154
else {
136-
return this.jsonMapper.readValue(bytes, javaType);
155+
return this.mapper.readValue(bytes, javaType);
137156
}
138157
}
139158
else {
140159
// Assuming a text-based source payload
141160
if (view != null) {
142-
return this.jsonMapper.readerWithView(view).forType(javaType).readValue(payload.toString());
161+
return this.mapper.readerWithView(view).forType(javaType).readValue(payload.toString());
143162
}
144163
else {
145-
return this.jsonMapper.readValue(payload.toString(), javaType);
164+
return this.mapper.readValue(payload.toString(), javaType);
146165
}
147166
}
148167
}
@@ -160,12 +179,12 @@ else if (payload instanceof byte[] bytes) {
160179
if (byte[].class == getSerializedPayloadClass()) {
161180
ByteArrayOutputStream out = new ByteArrayOutputStream(1024);
162181
JsonEncoding encoding = getJsonEncoding(getMimeType(headers));
163-
try (JsonGenerator generator = this.jsonMapper.createGenerator(out, encoding)) {
182+
try (JsonGenerator generator = this.mapper.createGenerator(out, encoding)) {
164183
if (view != null) {
165-
this.jsonMapper.writerWithView(view).writeValue(generator, payload);
184+
this.mapper.writerWithView(view).writeValue(generator, payload);
166185
}
167186
else {
168-
this.jsonMapper.writeValue(generator, payload);
187+
this.mapper.writeValue(generator, payload);
169188
}
170189
payload = out.toByteArray();
171190
}
@@ -174,10 +193,10 @@ else if (payload instanceof byte[] bytes) {
174193
// Assuming a text-based target payload
175194
Writer writer = new StringWriter(1024);
176195
if (view != null) {
177-
this.jsonMapper.writerWithView(view).writeValue(writer, payload);
196+
this.mapper.writerWithView(view).writeValue(writer, payload);
178197
}
179198
else {
180-
this.jsonMapper.writeValue(writer, payload);
199+
this.mapper.writeValue(writer, payload);
181200
}
182201
payload = writer.toString();
183202
}

spring-web/src/main/java/org/springframework/http/codec/cbor/JacksonCborDecoder.java

Lines changed: 22 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -51,17 +51,38 @@ public JacksonCborDecoder() {
5151
super(CBORMapper.builder(), MediaType.APPLICATION_CBOR);
5252
}
5353

54+
/**
55+
* Construct a new instance with the provided {@link CBORMapper.Builder}
56+
* customized with the {@link tools.jackson.databind.JacksonModule}s
57+
* found by {@link MapperBuilder#findModules(ClassLoader)}.
58+
* @see CBORMapper#builder()
59+
*/
60+
public JacksonCborDecoder(CBORMapper.Builder builder) {
61+
super(builder, MediaType.APPLICATION_CBOR);
62+
}
63+
5464
/**
5565
* Construct a new instance with the provided {@link CBORMapper}.
66+
* @see CBORMapper#builder()
5667
*/
5768
public JacksonCborDecoder(CBORMapper mapper) {
5869
super(mapper, MediaType.APPLICATION_CBOR);
5970
}
6071

72+
/**
73+
* Construct a new instance with the provided {@link CBORMapper.Builder}
74+
* customized with the {@link tools.jackson.databind.JacksonModule}s
75+
* found by {@link MapperBuilder#findModules(ClassLoader)}, and
76+
* {@link MimeType}s.
77+
* @see CBORMapper#builder()
78+
*/
79+
public JacksonCborDecoder(CBORMapper.Builder builder, MimeType... mimeTypes) {
80+
super(builder, mimeTypes);
81+
}
82+
6183
/**
6284
* Construct a new instance with the provided {@link CBORMapper} and {@link MimeType}s.
6385
* @see CBORMapper#builder()
64-
* @see MapperBuilder#findAndAddModules(ClassLoader)
6586
*/
6687
public JacksonCborDecoder(CBORMapper mapper, MimeType... mimeTypes) {
6788
super(mapper, mimeTypes);

spring-web/src/main/java/org/springframework/http/codec/cbor/JacksonCborEncoder.java

Lines changed: 21 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -52,19 +52,38 @@ public JacksonCborEncoder() {
5252
super(CBORMapper.builder(), MediaType.APPLICATION_CBOR);
5353
}
5454

55+
/**
56+
* Construct a new instance with the provided {@link CBORMapper.Builder}
57+
* customized with the {@link tools.jackson.databind.JacksonModule}s
58+
* found by {@link MapperBuilder#findModules(ClassLoader)}.
59+
* @see CBORMapper#builder()
60+
*/
61+
public JacksonCborEncoder(CBORMapper.Builder builder) {
62+
super(builder, MediaType.APPLICATION_CBOR);
63+
}
64+
5565
/**
5666
* Construct a new instance with the provided {@link CBORMapper}.
5767
* @see CBORMapper#builder()
58-
* @see MapperBuilder#findAndAddModules(ClassLoader)
5968
*/
6069
public JacksonCborEncoder(CBORMapper mapper) {
6170
super(mapper, MediaType.APPLICATION_CBOR);
6271
}
6372

73+
/**
74+
* Construct a new instance with the provided {@link CBORMapper.Builder}
75+
* customized with the {@link tools.jackson.databind.JacksonModule}s
76+
* found by {@link MapperBuilder#findModules(ClassLoader)}, and
77+
* {@link MimeType}s.
78+
* @see CBORMapper#builder()
79+
*/
80+
public JacksonCborEncoder(CBORMapper.Builder builder, MimeType... mimeTypes) {
81+
super(builder, mimeTypes);
82+
}
83+
6484
/**
6585
* Construct a new instance with the provided {@link CBORMapper} and {@link MimeType}s.
6686
* @see CBORMapper#builder()
67-
* @see MapperBuilder#findAndAddModules(ClassLoader)
6887
*/
6988
public JacksonCborEncoder(CBORMapper mapper, MimeType... mimeTypes) {
7089
super(mapper, mimeTypes);

0 commit comments

Comments
 (0)