11/*
2- * Copyright 2002-2015 the original author or authors.
2+ * Copyright 2002-2016 the original author or authors.
33 *
44 * Licensed under the Apache License, Version 2.0 (the "License");
55 * you may not use this file except in compliance with the License.
2929import javax .jms .Session ;
3030import javax .jms .TextMessage ;
3131
32+ import com .fasterxml .jackson .annotation .JsonView ;
3233import com .fasterxml .jackson .databind .DeserializationFeature ;
3334import com .fasterxml .jackson .databind .JavaType ;
3435import com .fasterxml .jackson .databind .MapperFeature ;
3536import com .fasterxml .jackson .databind .ObjectMapper ;
37+ import com .fasterxml .jackson .databind .ObjectWriter ;
3638
3739import org .springframework .beans .factory .BeanClassLoaderAware ;
40+ import org .springframework .core .MethodParameter ;
3841import org .springframework .util .Assert ;
3942import org .springframework .util .ClassUtils ;
4043
5558 * @author Mark Pollack
5659 * @author Dave Syer
5760 * @author Juergen Hoeller
61+ * @author Stephane Nicoll
5862 * @since 3.1.4
5963 */
60- public class MappingJackson2MessageConverter implements MessageConverter , BeanClassLoaderAware {
64+ public class MappingJackson2MessageConverter implements SmartMessageConverter , BeanClassLoaderAware {
6165
6266 /**
6367 * 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
189193 return message ;
190194 }
191195
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+
192223 @ Override
193224 public Object fromMessage (Message message ) throws JMSException , MessageConversionException {
194225 try {
@@ -200,6 +231,28 @@ public Object fromMessage(Message message) throws JMSException, MessageConversio
200231 }
201232 }
202233
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+
203256
204257 /**
205258 * Map the given object to a {@link TextMessage}.
@@ -210,12 +263,31 @@ public Object fromMessage(Message message) throws JMSException, MessageConversio
210263 * @throws JMSException if thrown by JMS methods
211264 * @throws IOException in case of I/O errors
212265 * @see Session#createBytesMessage
266+ * @deprecated as of 4.3, use {@link #mapToTextMessage(Object, Session, ObjectWriter)}
213267 */
268+ @ Deprecated
214269 protected TextMessage mapToTextMessage (Object object , Session session , ObjectMapper objectMapper )
215270 throws JMSException , IOException {
216271
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+
217289 StringWriter writer = new StringWriter ();
218- objectMapper .writeValue (writer , object );
290+ objectWriter .writeValue (writer , object );
219291 return session .createTextMessage (writer .toString ());
220292 }
221293
@@ -228,13 +300,33 @@ protected TextMessage mapToTextMessage(Object object, Session session, ObjectMap
228300 * @throws JMSException if thrown by JMS methods
229301 * @throws IOException in case of I/O errors
230302 * @see Session#createBytesMessage
303+ * @deprecated as of 4.3, use {@link #mapToBytesMessage(Object, Session, ObjectWriter)}
231304 */
305+ @ Deprecated
232306 protected BytesMessage mapToBytesMessage (Object object , Session session , ObjectMapper objectMapper )
233307 throws JMSException , IOException {
234308
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+
235327 ByteArrayOutputStream bos = new ByteArrayOutputStream (1024 );
236328 OutputStreamWriter writer = new OutputStreamWriter (bos , this .encoding );
237- objectMapper .writeValue (writer , object );
329+ objectWriter .writeValue (writer , object );
238330
239331 BytesMessage message = session .createBytesMessage ();
240332 message .writeBytes (bos .toByteArray ());
@@ -256,10 +348,31 @@ protected BytesMessage mapToBytesMessage(Object object, Session session, ObjectM
256348 * @return the resulting message
257349 * @throws JMSException if thrown by JMS methods
258350 * @throws IOException in case of I/O errors
351+ * @deprecated as of 4.3, use {@link #mapToMessage(Object, Session, ObjectWriter, MessageType)}
259352 */
353+ @ Deprecated
260354 protected Message mapToMessage (Object object , Session session , ObjectMapper objectMapper , MessageType targetType )
261355 throws JMSException , IOException {
262356
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+
263376 throw new IllegalArgumentException ("Unsupported message type [" + targetType +
264377 "]. MappingJackson2MessageConverter by default only supports TextMessages and BytesMessages." );
265378 }
@@ -391,4 +504,42 @@ protected JavaType getJavaTypeForMessage(Message message) throws JMSException {
391504 }
392505 }
393506
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+
394545}
0 commit comments