View Javadoc
1   /*
2    * Copyright 2002-2015 the original author or authors.
3    *
4    * Licensed under the Apache License, Version 2.0 (the "License");
5    * you may not use this file except in compliance with the License.
6    * You may obtain a copy of the License at
7    *
8    *      http://www.apache.org/licenses/LICENSE-2.0
9    *
10   * Unless required by applicable law or agreed to in writing, software
11   * distributed under the License is distributed on an "AS IS" BASIS,
12   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13   * See the License for the specific language governing permissions and
14   * limitations under the License.
15   */
16  
17  package org.springframework.messaging.converter;
18  
19  import java.io.IOException;
20  import java.nio.charset.Charset;
21  import java.util.Arrays;
22  import java.util.HashMap;
23  import java.util.Map;
24  
25  import com.fasterxml.jackson.databind.DeserializationFeature;
26  import org.junit.Test;
27  
28  import org.springframework.messaging.Message;
29  import org.springframework.messaging.MessageHeaders;
30  import org.springframework.messaging.support.MessageBuilder;
31  import org.springframework.util.MimeType;
32  
33  import static org.hamcrest.Matchers.*;
34  import static org.junit.Assert.*;
35  
36  /**
37   * Test fixture for {@link org.springframework.messaging.converter.MappingJackson2MessageConverter}.
38   *
39   * @author Rossen Stoyanchev
40   * @author Sebastien Deleuze
41   */
42  public class MappingJackson2MessageConverterTests {
43  
44  	private static Charset UTF_8 = Charset.forName("UTF-8");
45  
46  
47  	@Test
48  	public void defaultConstructor() {
49  		MappingJackson2MessageConverter converter = new MappingJackson2MessageConverter();
50  		assertThat(converter.getSupportedMimeTypes(), contains(new MimeType("application", "json", UTF_8)));
51  		assertFalse(converter.getObjectMapper().getDeserializationConfig().isEnabled(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES));
52  	}
53  
54  	@Test  // SPR-12724
55  	public void mimetypeParametrizedConstructor() {
56  		MimeType mimetype = new MimeType("application", "xml", UTF_8);
57  		MappingJackson2MessageConverter converter = new MappingJackson2MessageConverter(mimetype);
58  		assertThat(converter.getSupportedMimeTypes(), contains(mimetype));
59  		assertFalse(converter.getObjectMapper().getDeserializationConfig().isEnabled(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES));
60  	}
61  
62  	@Test  // SPR-12724
63  	public void mimetypesParametrizedConstructor() {
64  		MimeType jsonMimetype = new MimeType("application", "json", UTF_8);
65  		MimeType xmlMimetype = new MimeType("application", "xml", UTF_8);
66  		MappingJackson2MessageConverter converter = new MappingJackson2MessageConverter(jsonMimetype, xmlMimetype);
67  		assertThat(converter.getSupportedMimeTypes(), contains(jsonMimetype, xmlMimetype));
68  		assertFalse(converter.getObjectMapper().getDeserializationConfig().isEnabled(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES));
69  	}
70  
71  	@Test
72  	public void fromMessage() throws Exception {
73  		MappingJackson2MessageConverter converter = new MappingJackson2MessageConverter();
74  		String payload = "{\"bytes\":\"AQI=\",\"array\":[\"Foo\",\"Bar\"],"
75  				+ "\"number\":42,\"string\":\"Foo\",\"bool\":true,\"fraction\":42.0}";
76  		Message<?> message = MessageBuilder.withPayload(payload.getBytes(UTF_8)).build();
77  		MyBean actual = (MyBean) converter.fromMessage(message, MyBean.class);
78  
79  		assertEquals("Foo", actual.getString());
80  		assertEquals(42, actual.getNumber());
81  		assertEquals(42F, actual.getFraction(), 0F);
82  		assertArrayEquals(new String[]{"Foo", "Bar"}, actual.getArray());
83  		assertTrue(actual.isBool());
84  		assertArrayEquals(new byte[]{0x1, 0x2}, actual.getBytes());
85  	}
86  
87  	@Test
88  	public void fromMessageUntyped() throws Exception {
89  		MappingJackson2MessageConverter converter = new MappingJackson2MessageConverter();
90  		String payload = "{\"bytes\":\"AQI=\",\"array\":[\"Foo\",\"Bar\"],"
91  				+ "\"number\":42,\"string\":\"Foo\",\"bool\":true,\"fraction\":42.0}";
92  		Message<?> message = MessageBuilder.withPayload(payload.getBytes(UTF_8)).build();
93  		@SuppressWarnings("unchecked")
94  		HashMap<String, Object> actual = (HashMap<String, Object>) converter.fromMessage(message, HashMap.class);
95  
96  		assertEquals("Foo", actual.get("string"));
97  		assertEquals(42, actual.get("number"));
98  		assertEquals(42D, (Double) actual.get("fraction"), 0D);
99  		assertEquals(Arrays.asList("Foo", "Bar"), actual.get("array"));
100 		assertEquals(Boolean.TRUE, actual.get("bool"));
101 		assertEquals("AQI=", actual.get("bytes"));
102 	}
103 
104 	@Test(expected = MessageConversionException.class)
105 	public void fromMessageInvalidJson() throws Exception {
106 		MappingJackson2MessageConverter converter = new MappingJackson2MessageConverter();
107 		String payload = "FooBar";
108 		Message<?> message = MessageBuilder.withPayload(payload.getBytes(UTF_8)).build();
109 		converter.fromMessage(message, MyBean.class);
110 	}
111 
112 	@Test
113 	public void fromMessageValidJsonWithUnknownProperty() throws IOException {
114 		MappingJackson2MessageConverter converter = new MappingJackson2MessageConverter();
115 		String payload = "{\"string\":\"string\",\"unknownProperty\":\"value\"}";
116 		Message<?> message = MessageBuilder.withPayload(payload.getBytes(UTF_8)).build();
117 		MyBean myBean = (MyBean)converter.fromMessage(message, MyBean.class);
118 		assertEquals("string", myBean.getString());
119 	}
120 
121 	@Test
122 	public void toMessage() throws Exception {
123 		MappingJackson2MessageConverter converter = new MappingJackson2MessageConverter();
124 		MyBean payload = new MyBean();
125 		payload.setString("Foo");
126 		payload.setNumber(42);
127 		payload.setFraction(42F);
128 		payload.setArray(new String[]{"Foo", "Bar"});
129 		payload.setBool(true);
130 		payload.setBytes(new byte[]{0x1, 0x2});
131 
132 		Message<?> message = converter.toMessage(payload, null);
133 		String actual = new String((byte[]) message.getPayload(), UTF_8);
134 
135 		assertTrue(actual.contains("\"string\":\"Foo\""));
136 		assertTrue(actual.contains("\"number\":42"));
137 		assertTrue(actual.contains("fraction\":42.0"));
138 		assertTrue(actual.contains("\"array\":[\"Foo\",\"Bar\"]"));
139 		assertTrue(actual.contains("\"bool\":true"));
140 		assertTrue(actual.contains("\"bytes\":\"AQI=\""));
141 		assertEquals("Invalid content-type", new MimeType("application", "json", UTF_8),
142 				message.getHeaders().get(MessageHeaders.CONTENT_TYPE, MimeType.class));
143 	}
144 
145 	@Test
146 	public void toMessageUtf16() {
147 		MappingJackson2MessageConverter converter = new MappingJackson2MessageConverter();
148 		Charset utf16 = Charset.forName("UTF-16BE");
149 		MimeType contentType = new MimeType("application", "json", utf16);
150 		Map<String, Object> map = new HashMap<>();
151 		map.put(MessageHeaders.CONTENT_TYPE, contentType);
152 		MessageHeaders headers = new MessageHeaders(map);
153 		String payload = "H\u00e9llo W\u00f6rld";
154 		Message<?> message = converter.toMessage(payload, headers);
155 
156 		assertEquals("\"" + payload + "\"", new String((byte[]) message.getPayload(), utf16));
157 		assertEquals(contentType, message.getHeaders().get(MessageHeaders.CONTENT_TYPE));
158 	}
159 
160 	@Test
161 	public void toMessageUtf16String() {
162 		MappingJackson2MessageConverter converter = new MappingJackson2MessageConverter();
163 		converter.setSerializedPayloadClass(String.class);
164 
165 		Charset utf16 = Charset.forName("UTF-16BE");
166 		MimeType contentType = new MimeType("application", "json", utf16);
167 		Map<String, Object> map = new HashMap<>();
168 		map.put(MessageHeaders.CONTENT_TYPE, contentType);
169 		MessageHeaders headers = new MessageHeaders(map);
170 		String payload = "H\u00e9llo W\u00f6rld";
171 		Message<?> message = converter.toMessage(payload, headers);
172 
173 		assertEquals("\"" + payload + "\"", message.getPayload());
174 		assertEquals(contentType, message.getHeaders().get(MessageHeaders.CONTENT_TYPE));
175 	}
176 
177 
178 	public static class MyBean {
179 
180 		private String string;
181 
182 		private int number;
183 
184 		private float fraction;
185 
186 		private String[] array;
187 
188 		private boolean bool;
189 
190 		private byte[] bytes;
191 
192 		public byte[] getBytes() {
193 			return bytes;
194 		}
195 
196 		public void setBytes(byte[] bytes) {
197 			this.bytes = bytes;
198 		}
199 
200 		public boolean isBool() {
201 			return bool;
202 		}
203 
204 		public void setBool(boolean bool) {
205 			this.bool = bool;
206 		}
207 
208 		public String getString() {
209 			return string;
210 		}
211 
212 		public void setString(String string) {
213 			this.string = string;
214 		}
215 
216 		public int getNumber() {
217 			return number;
218 		}
219 
220 		public void setNumber(int number) {
221 			this.number = number;
222 		}
223 
224 		public float getFraction() {
225 			return fraction;
226 		}
227 
228 		public void setFraction(float fraction) {
229 			this.fraction = fraction;
230 		}
231 
232 		public String[] getArray() {
233 			return array;
234 		}
235 
236 		public void setArray(String[] array) {
237 			this.array = array;
238 		}
239 	}
240 
241 }