1
1
/*
2
- * Copyright 2002-2015 the original author or authors.
2
+ * Copyright 2002-2016 the original author or authors.
3
3
*
4
4
* Licensed under the Apache License, Version 2.0 (the "License");
5
5
* you may not use this file except in compliance with the License.
29
29
import javax .jms .Session ;
30
30
import javax .jms .TextMessage ;
31
31
32
+ import com .fasterxml .jackson .annotation .JsonView ;
32
33
import com .fasterxml .jackson .databind .DeserializationFeature ;
33
34
import com .fasterxml .jackson .databind .JavaType ;
34
35
import com .fasterxml .jackson .databind .MapperFeature ;
35
36
import com .fasterxml .jackson .databind .ObjectMapper ;
37
+ import com .fasterxml .jackson .databind .ObjectWriter ;
36
38
37
39
import org .springframework .beans .factory .BeanClassLoaderAware ;
40
+ import org .springframework .core .MethodParameter ;
38
41
import org .springframework .util .Assert ;
39
42
import org .springframework .util .ClassUtils ;
40
43
55
58
* @author Mark Pollack
56
59
* @author Dave Syer
57
60
* @author Juergen Hoeller
61
+ * @author Stephane Nicoll
58
62
* @since 3.1.4
59
63
*/
60
- public class MappingJackson2MessageConverter implements MessageConverter , BeanClassLoaderAware {
64
+ public class MappingJackson2MessageConverter implements SmartMessageConverter , BeanClassLoaderAware {
61
65
62
66
/**
63
67
* The default encoding used for writing to text messages: UTF-8.
@@ -189,6 +193,33 @@ public Message toMessage(Object object, Session session) throws JMSException, Me
189
193
return message ;
190
194
}
191
195
196
+ @ Override
197
+ public Message toMessage (Object object , Session session , Object conversionHint )
198
+ throws JMSException , MessageConversionException {
199
+ return toMessage (object , session , getSerializationView (conversionHint ));
200
+ }
201
+
202
+ /**
203
+ * Convert a Java object to a JMS Message using the specified json view
204
+ * and the supplied session to create the message object.
205
+ * @param object the object to convert
206
+ * @param session the Session to use for creating a JMS Message
207
+ * @param jsonView the view to use to filter the content
208
+ * @return the JMS Message
209
+ * @throws javax.jms.JMSException if thrown by JMS API methods
210
+ * @throws MessageConversionException in case of conversion failure
211
+ * @since 4.3
212
+ */
213
+ public Message toMessage (Object object , Session session , Class <?> jsonView )
214
+ throws JMSException , MessageConversionException {
215
+ if (jsonView != null ) {
216
+ return toMessage (object , session , this .objectMapper .writerWithView (jsonView ));
217
+ }
218
+ else {
219
+ return toMessage (object , session , this .objectMapper .writer ());
220
+ }
221
+ }
222
+
192
223
@ Override
193
224
public Object fromMessage (Message message ) throws JMSException , MessageConversionException {
194
225
try {
@@ -200,6 +231,28 @@ public Object fromMessage(Message message) throws JMSException, MessageConversio
200
231
}
201
232
}
202
233
234
+ protected Message toMessage (Object object , Session session , ObjectWriter objectWriter )
235
+ throws JMSException , MessageConversionException {
236
+ Message message ;
237
+ try {
238
+ switch (this .targetType ) {
239
+ case TEXT :
240
+ message = mapToTextMessage (object , session , objectWriter );
241
+ break ;
242
+ case BYTES :
243
+ message = mapToBytesMessage (object , session , objectWriter );
244
+ break ;
245
+ default :
246
+ message = mapToMessage (object , session , objectWriter , this .targetType );
247
+ }
248
+ }
249
+ catch (IOException ex ) {
250
+ throw new MessageConversionException ("Could not map JSON object [" + object + "]" , ex );
251
+ }
252
+ setTypeIdOnMessage (object , message );
253
+ return message ;
254
+ }
255
+
203
256
204
257
/**
205
258
* Map the given object to a {@link TextMessage}.
@@ -210,12 +263,31 @@ public Object fromMessage(Message message) throws JMSException, MessageConversio
210
263
* @throws JMSException if thrown by JMS methods
211
264
* @throws IOException in case of I/O errors
212
265
* @see Session#createBytesMessage
266
+ * @deprecated as of 4.3, use {@link #mapToTextMessage(Object, Session, ObjectWriter)}
213
267
*/
268
+ @ Deprecated
214
269
protected TextMessage mapToTextMessage (Object object , Session session , ObjectMapper objectMapper )
215
270
throws JMSException , IOException {
216
271
272
+ return mapToTextMessage (object , session , objectMapper .writer ());
273
+ }
274
+
275
+ /**
276
+ * Map the given object to a {@link TextMessage}.
277
+ * @param object the object to be mapped
278
+ * @param session current JMS session
279
+ * @param objectWriter the writer to use
280
+ * @return the resulting message
281
+ * @throws JMSException if thrown by JMS methods
282
+ * @throws IOException in case of I/O errors
283
+ * @see Session#createBytesMessage
284
+ * @since 4.3
285
+ */
286
+ protected TextMessage mapToTextMessage (Object object , Session session , ObjectWriter objectWriter )
287
+ throws JMSException , IOException {
288
+
217
289
StringWriter writer = new StringWriter ();
218
- objectMapper .writeValue (writer , object );
290
+ objectWriter .writeValue (writer , object );
219
291
return session .createTextMessage (writer .toString ());
220
292
}
221
293
@@ -228,13 +300,33 @@ protected TextMessage mapToTextMessage(Object object, Session session, ObjectMap
228
300
* @throws JMSException if thrown by JMS methods
229
301
* @throws IOException in case of I/O errors
230
302
* @see Session#createBytesMessage
303
+ * @deprecated as of 4.3, use {@link #mapToBytesMessage(Object, Session, ObjectWriter)}
231
304
*/
305
+ @ Deprecated
232
306
protected BytesMessage mapToBytesMessage (Object object , Session session , ObjectMapper objectMapper )
233
307
throws JMSException , IOException {
234
308
309
+ return mapToBytesMessage (object , session , objectMapper .writer ());
310
+ }
311
+
312
+
313
+ /**
314
+ * Map the given object to a {@link BytesMessage}.
315
+ * @param object the object to be mapped
316
+ * @param session current JMS session
317
+ * @param objectWriter the writer to use
318
+ * @return the resulting message
319
+ * @throws JMSException if thrown by JMS methods
320
+ * @throws IOException in case of I/O errors
321
+ * @see Session#createBytesMessage
322
+ * @since 4.3
323
+ */
324
+ protected BytesMessage mapToBytesMessage (Object object , Session session , ObjectWriter objectWriter )
325
+ throws JMSException , IOException {
326
+
235
327
ByteArrayOutputStream bos = new ByteArrayOutputStream (1024 );
236
328
OutputStreamWriter writer = new OutputStreamWriter (bos , this .encoding );
237
- objectMapper .writeValue (writer , object );
329
+ objectWriter .writeValue (writer , object );
238
330
239
331
BytesMessage message = session .createBytesMessage ();
240
332
message .writeBytes (bos .toByteArray ());
@@ -256,10 +348,31 @@ protected BytesMessage mapToBytesMessage(Object object, Session session, ObjectM
256
348
* @return the resulting message
257
349
* @throws JMSException if thrown by JMS methods
258
350
* @throws IOException in case of I/O errors
351
+ * @deprecated as of 4.3, use {@link #mapToMessage(Object, Session, ObjectWriter, MessageType)}
259
352
*/
353
+ @ Deprecated
260
354
protected Message mapToMessage (Object object , Session session , ObjectMapper objectMapper , MessageType targetType )
261
355
throws JMSException , IOException {
262
356
357
+ return mapToMessage (object , session , objectMapper .writer (), targetType );
358
+ }
359
+
360
+ /**
361
+ * Template method that allows for custom message mapping.
362
+ * Invoked when {@link #setTargetType} is not {@link MessageType#TEXT} or
363
+ * {@link MessageType#BYTES}.
364
+ * <p>The default implementation throws an {@link IllegalArgumentException}.
365
+ * @param object the object to marshal
366
+ * @param session the JMS Session
367
+ * @param objectWriter the writer to use
368
+ * @param targetType the target message type (other than TEXT or BYTES)
369
+ * @return the resulting message
370
+ * @throws JMSException if thrown by JMS methods
371
+ * @throws IOException in case of I/O errors
372
+ */
373
+ protected Message mapToMessage (Object object , Session session , ObjectWriter objectWriter , MessageType targetType )
374
+ throws JMSException , IOException {
375
+
263
376
throw new IllegalArgumentException ("Unsupported message type [" + targetType +
264
377
"]. MappingJackson2MessageConverter by default only supports TextMessages and BytesMessages." );
265
378
}
@@ -391,4 +504,42 @@ protected JavaType getJavaTypeForMessage(Message message) throws JMSException {
391
504
}
392
505
}
393
506
507
+ /**
508
+ * Determine a Jackson serialization view based on the given conversion hint.
509
+ * @param conversionHint the conversion hint Object as passed into the
510
+ * converter for the current conversion attempt
511
+ * @return the serialization view class, or {@code null} if none
512
+ */
513
+ protected Class <?> getSerializationView (Object conversionHint ) {
514
+ if (conversionHint instanceof MethodParameter ) {
515
+ MethodParameter methodParam = (MethodParameter ) conversionHint ;
516
+ JsonView annotation = methodParam .getParameterAnnotation (JsonView .class );
517
+ if (annotation == null ) {
518
+ annotation = methodParam .getMethodAnnotation (JsonView .class );
519
+ if (annotation == null ) {
520
+ return null ;
521
+ }
522
+ }
523
+ return extractViewClass (annotation , conversionHint );
524
+ }
525
+ else if (conversionHint instanceof JsonView ) {
526
+ return extractViewClass ((JsonView ) conversionHint , conversionHint );
527
+ }
528
+ else if (conversionHint instanceof Class ) {
529
+ return (Class ) conversionHint ;
530
+ }
531
+ else {
532
+ return null ;
533
+ }
534
+ }
535
+
536
+ private Class <?> extractViewClass (JsonView annotation , Object conversionHint ) {
537
+ Class <?>[] classes = annotation .value ();
538
+ if (classes .length != 1 ) {
539
+ throw new IllegalArgumentException (
540
+ "@JsonView only supported for handler methods with exactly 1 class argument: " + conversionHint );
541
+ }
542
+ return classes [0 ];
543
+ }
544
+
394
545
}
0 commit comments