1
16
17 package org.springframework.cloud.aws.messaging.support.converter;
18
19 import java.io.ByteArrayInputStream;
20 import java.io.ByteArrayOutputStream;
21 import java.io.IOException;
22 import java.io.ObjectInputStream;
23 import java.io.ObjectOutputStream;
24 import java.io.Serializable;
25 import java.nio.charset.Charset;
26
27 import org.apache.commons.codec.binary.Base64;
28 import org.apache.commons.codec.binary.Base64InputStream;
29 import org.apache.commons.codec.binary.Base64OutputStream;
30 import org.slf4j.Logger;
31 import org.slf4j.LoggerFactory;
32
33 import org.springframework.messaging.Message;
34 import org.springframework.messaging.MessageHeaders;
35 import org.springframework.messaging.converter.AbstractMessageConverter;
36 import org.springframework.messaging.converter.MessageConversionException;
37 import org.springframework.util.MimeType;
38
39
42 public class ObjectMessageConverter extends AbstractMessageConverter {
43
44 private static final Logger LOGGER = LoggerFactory
45 .getLogger(ObjectMessageConverter.class);
46
47 private static final String DEFAULT_ENCODING = "UTF-8";
48
49 private final Charset encoding;
50
51 public ObjectMessageConverter(String encoding) {
52 super(new MimeType("application", "x-java-serialized-object",
53 Charset.forName(encoding)));
54 this.encoding = Charset.forName(encoding);
55 }
56
57 public ObjectMessageConverter() {
58 this(DEFAULT_ENCODING);
59 }
60
61 @Override
62 protected boolean supports(Class<?> clazz) {
63 return true;
64 }
65
66 @SuppressWarnings("deprecation")
67 @Override
68 public Object convertFromInternal(Message<?> message, Class<?> targetClass,
69 Object conversionHint) {
70 String messagePayload = message.getPayload().toString();
71 byte[] rawContent = messagePayload.getBytes(this.encoding);
72 if (!(Base64.isBase64(rawContent))) {
73 throw new MessageConversionException(
74 "Error converting payload '" + messagePayload
75 + "' because it is not a valid base64 encoded stream!",
76 null);
77 }
78 ByteArrayInputStream byteArrayInputStream = new ByteArrayInputStream(rawContent);
79 Base64InputStream base64InputStream = new Base64InputStream(byteArrayInputStream);
80 Serializable result;
81 ObjectInputStream objectInputStream = null;
82 try {
83 objectInputStream = new ObjectInputStream(base64InputStream);
84 result = (Serializable) objectInputStream.readObject();
85 }
86 catch (ClassNotFoundException e) {
87 throw new MessageConversionException(
88 "Error loading class from message payload, make sure class is in classpath!",
89 e);
90 }
91 catch (IOException e) {
92 throw new MessageConversionException(
93 "Error reading payload from binary representation", e);
94 }
95 finally {
96 if (objectInputStream != null) {
97 try {
98 objectInputStream.close();
99 }
100 catch (IOException e) {
101 LOGGER.warn(
102 "Error closing object output stream while reading message payload",
103 e);
104 }
105 }
106 }
107
108 return result;
109 }
110
111 @SuppressWarnings("deprecation")
112 @Override
113 public Object convertToInternal(Object payload, MessageHeaders headers,
114 Object conversionHint) {
115 if (!(payload instanceof Serializable)) {
116 throw new IllegalArgumentException(
117 "Can't convert payload, it must be of type Serializable");
118 }
119
120 ByteArrayOutputStream content = new ByteArrayOutputStream();
121 Base64OutputStream base64OutputStream = new Base64OutputStream(content, true, 0,
122 null);
123 ObjectOutputStream objectOutputStream = null;
124 try {
125 objectOutputStream = new ObjectOutputStream(base64OutputStream);
126 objectOutputStream.writeObject(payload);
127 objectOutputStream.flush();
128 }
129 catch (IOException e) {
130 throw new MessageConversionException(
131 "Error converting payload into binary representation", e);
132 }
133 finally {
134 if (objectOutputStream != null) {
135 try {
136 objectOutputStream.close();
137 }
138 catch (IOException e) {
139 LOGGER.warn(
140 "Error closing object output stream while writing message payload",
141 e);
142 }
143 }
144 }
145
146 return new String(content.toByteArray(), 0, content.size(), this.encoding);
147 }
148
149 }
150