下面列出了怎么用org.springframework.http.MockHttpInputMessage的API类实例代码及写法,或者点击链接到github查看源代码。
@Test
public void readTyped() throws IOException {
String body = "{" +
"\"bytes\":\"AQI=\"," +
"\"array\":[\"Foo\",\"Bar\"]," +
"\"number\":42," +
"\"string\":\"Foo\"," +
"\"bool\":true," +
"\"fraction\":42.0}";
MockHttpInputMessage inputMessage = new MockHttpInputMessage(body.getBytes("UTF-8"));
inputMessage.getHeaders().setContentType(new MediaType("application", "json"));
MyBean result = (MyBean) converter.read(MyBean.class, inputMessage);
assertEquals("Foo", result.getString());
assertEquals(42, result.getNumber());
assertEquals(42F, result.getFraction(), 0F);
assertArrayEquals(new String[] {"Foo", "Bar"}, result.getArray());
assertTrue(result.isBool());
assertArrayEquals(new byte[] {0x1, 0x2}, result.getBytes());
}
@Test
@SuppressWarnings("unchecked")
public void readUntyped() throws IOException {
String body = "{\"bytes\":[1,2],\"array\":[\"Foo\",\"Bar\"]," +
"\"number\":42,\"string\":\"Foo\",\"bool\":true,\"fraction\":42.0}";
MockHttpInputMessage inputMessage = new MockHttpInputMessage(body.getBytes("UTF-8"));
inputMessage.getHeaders().setContentType(new MediaType("application", "json"));
HashMap<String, Object> result = (HashMap<String, Object>) this.converter.read(HashMap.class, inputMessage);
assertEquals("Foo", result.get("string"));
Number n = (Number) result.get("number");
assertEquals(42, n.longValue());
n = (Number) result.get("fraction");
assertEquals(42D, n.doubleValue(), 0D);
List<String> array = new ArrayList<>();
array.add("Foo");
array.add("Bar");
assertEquals(array, result.get("array"));
assertEquals(Boolean.TRUE, result.get("bool"));
byte[] bytes = new byte[2];
List<Number> resultBytes = (ArrayList<Number>)result.get("bytes");
for (int i = 0; i < 2; i++) {
bytes[i] = resultBytes.get(i).byteValue();
}
assertArrayEquals(new byte[] {0x1, 0x2}, bytes);
}
@Test
@SuppressWarnings("unchecked")
public void readUntyped() throws IOException {
String body = "{\"bytes\":[1,2],\"array\":[\"Foo\",\"Bar\"]," +
"\"number\":42,\"string\":\"Foo\",\"bool\":true,\"fraction\":42.0}";
MockHttpInputMessage inputMessage = new MockHttpInputMessage(body.getBytes("UTF-8"));
inputMessage.getHeaders().setContentType(new MediaType("application", "json"));
HashMap<String, Object> result = (HashMap<String, Object>) this.converter.read(HashMap.class, inputMessage);
assertEquals("Foo", result.get("string"));
Number n = (Number) result.get("number");
assertEquals(42, n.longValue());
n = (Number) result.get("fraction");
assertEquals(42D, n.doubleValue(), 0D);
List<String> array = new ArrayList<>();
array.add("Foo");
array.add("Bar");
assertEquals(array, result.get("array"));
assertEquals(Boolean.TRUE, result.get("bool"));
byte[] bytes = new byte[2];
List<Number> resultBytes = (ArrayList<Number>)result.get("bytes");
for (int i = 0; i < 2; i++) {
bytes[i] = resultBytes.get(i).byteValue();
}
assertArrayEquals(new byte[] {0x1, 0x2}, bytes);
}
@Test
@SuppressWarnings("unchecked")
public void readAndWriteGenerics() throws Exception {
Field beansList = ListHolder.class.getField("listField");
String body = "[{\"bytes\":[1,2],\"array\":[\"Foo\",\"Bar\"]," +
"\"number\":42,\"string\":\"Foo\",\"bool\":true,\"fraction\":42.0}]";
MockHttpInputMessage inputMessage = new MockHttpInputMessage(body.getBytes(StandardCharsets.UTF_8));
inputMessage.getHeaders().setContentType(new MediaType("application", "json"));
Type genericType = beansList.getGenericType();
List<MyBean> results = (List<MyBean>) converter.read(genericType, MyBeanListHolder.class, inputMessage);
assertEquals(1, results.size());
MyBean result = results.get(0);
assertEquals("Foo", result.getString());
assertEquals(42, result.getNumber());
assertEquals(42F, result.getFraction(), 0F);
assertArrayEquals(new String[] {"Foo", "Bar"}, result.getArray());
assertTrue(result.isBool());
assertArrayEquals(new byte[] {0x1, 0x2}, result.getBytes());
MockHttpOutputMessage outputMessage = new MockHttpOutputMessage();
converter.write(results, genericType, new MediaType("application", "json"), outputMessage);
JSONAssert.assertEquals(body, outputMessage.getBodyAsString(StandardCharsets.UTF_8), true);
}
@Test
@SuppressWarnings("unchecked")
public void writeParameterizedBaseType() throws Exception {
ParameterizedTypeReference<List<MyBean>> beansList = new ParameterizedTypeReference<List<MyBean>>() {};
ParameterizedTypeReference<List<MyBase>> baseList = new ParameterizedTypeReference<List<MyBase>>() {};
String body = "[{\"bytes\":[1,2],\"array\":[\"Foo\",\"Bar\"]," +
"\"number\":42,\"string\":\"Foo\",\"bool\":true,\"fraction\":42.0}]";
MockHttpInputMessage inputMessage = new MockHttpInputMessage(body.getBytes(StandardCharsets.UTF_8));
inputMessage.getHeaders().setContentType(new MediaType("application", "json"));
List<MyBean> results = (List<MyBean>) converter.read(beansList.getType(), null, inputMessage);
assertEquals(1, results.size());
MyBean result = results.get(0);
assertEquals("Foo", result.getString());
assertEquals(42, result.getNumber());
assertEquals(42F, result.getFraction(), 0F);
assertArrayEquals(new String[] {"Foo", "Bar"}, result.getArray());
assertTrue(result.isBool());
assertArrayEquals(new byte[] {0x1, 0x2}, result.getBytes());
MockHttpOutputMessage outputMessage = new MockHttpOutputMessage();
converter.write(results, baseList.getType(), new MediaType("application", "json"), outputMessage);
JSONAssert.assertEquals(body, outputMessage.getBodyAsString(StandardCharsets.UTF_8), true);
}
@Test
@SuppressWarnings("unchecked")
public void readUntyped() throws IOException {
String body = "{\"bytes\":[1,2],\"array\":[\"Foo\",\"Bar\"]," +
"\"number\":42,\"string\":\"Foo\",\"bool\":true,\"fraction\":42.0}";
MockHttpInputMessage inputMessage = new MockHttpInputMessage(body.getBytes("UTF-8"));
inputMessage.getHeaders().setContentType(new MediaType("application", "json"));
HashMap<String, Object> result = (HashMap<String, Object>) this.converter.read(HashMap.class, inputMessage);
assertEquals("Foo", result.get("string"));
Number n = (Number) result.get("number");
assertEquals(42, n.longValue());
n = (Number) result.get("fraction");
assertEquals(42D, n.doubleValue(), 0D);
List<String> array = new ArrayList<>();
array.add("Foo");
array.add("Bar");
assertEquals(array, result.get("array"));
assertEquals(Boolean.TRUE, result.get("bool"));
byte[] bytes = new byte[2];
List<Number> resultBytes = (ArrayList<Number>)result.get("bytes");
for (int i = 0; i < 2; i++) {
bytes[i] = resultBytes.get(i).byteValue();
}
assertArrayEquals(new byte[] {0x1, 0x2}, bytes);
}
@Test
@SuppressWarnings("unchecked")
public void readAndWriteGenerics() throws Exception {
Field beansList = ListHolder.class.getField("listField");
String body = "[{\"bytes\":[1,2],\"array\":[\"Foo\",\"Bar\"]," +
"\"number\":42,\"string\":\"Foo\",\"bool\":true,\"fraction\":42.0}]";
MockHttpInputMessage inputMessage = new MockHttpInputMessage(body.getBytes(StandardCharsets.UTF_8));
inputMessage.getHeaders().setContentType(new MediaType("application", "json"));
Type genericType = beansList.getGenericType();
List<MyBean> results = (List<MyBean>) converter.read(genericType, MyBeanListHolder.class, inputMessage);
assertEquals(1, results.size());
MyBean result = results.get(0);
assertEquals("Foo", result.getString());
assertEquals(42, result.getNumber());
assertEquals(42F, result.getFraction(), 0F);
assertArrayEquals(new String[] {"Foo", "Bar"}, result.getArray());
assertTrue(result.isBool());
assertArrayEquals(new byte[] {0x1, 0x2}, result.getBytes());
MockHttpOutputMessage outputMessage = new MockHttpOutputMessage();
converter.write(results, genericType, new MediaType("application", "json"), outputMessage);
JSONAssert.assertEquals(body, outputMessage.getBodyAsString(StandardCharsets.UTF_8), true);
}
@Test
@SuppressWarnings("unchecked")
public void readAndWriteParameterizedType() throws Exception {
ParameterizedTypeReference<List<MyBean>> beansList = new ParameterizedTypeReference<List<MyBean>>() {};
String body = "[{\"bytes\":[1,2],\"array\":[\"Foo\",\"Bar\"]," +
"\"number\":42,\"string\":\"Foo\",\"bool\":true,\"fraction\":42.0}]";
MockHttpInputMessage inputMessage = new MockHttpInputMessage(body.getBytes(StandardCharsets.UTF_8));
inputMessage.getHeaders().setContentType(new MediaType("application", "json"));
List<MyBean> results = (List<MyBean>) converter.read(beansList.getType(), null, inputMessage);
assertEquals(1, results.size());
MyBean result = results.get(0);
assertEquals("Foo", result.getString());
assertEquals(42, result.getNumber());
assertEquals(42F, result.getFraction(), 0F);
assertArrayEquals(new String[] {"Foo", "Bar"}, result.getArray());
assertTrue(result.isBool());
assertArrayEquals(new byte[] {0x1, 0x2}, result.getBytes());
MockHttpOutputMessage outputMessage = new MockHttpOutputMessage();
converter.write(results, beansList.getType(), new MediaType("application", "json"), outputMessage);
JSONAssert.assertEquals(body, outputMessage.getBodyAsString(StandardCharsets.UTF_8), true);
}
@Test
@SuppressWarnings("unchecked")
public void writeParameterizedBaseType() throws Exception {
ParameterizedTypeReference<List<MyBean>> beansList = new ParameterizedTypeReference<List<MyBean>>() {};
ParameterizedTypeReference<List<MyBase>> baseList = new ParameterizedTypeReference<List<MyBase>>() {};
String body = "[{\"bytes\":[1,2],\"array\":[\"Foo\",\"Bar\"]," +
"\"number\":42,\"string\":\"Foo\",\"bool\":true,\"fraction\":42.0}]";
MockHttpInputMessage inputMessage = new MockHttpInputMessage(body.getBytes(StandardCharsets.UTF_8));
inputMessage.getHeaders().setContentType(new MediaType("application", "json"));
List<MyBean> results = (List<MyBean>) converter.read(beansList.getType(), null, inputMessage);
assertEquals(1, results.size());
MyBean result = results.get(0);
assertEquals("Foo", result.getString());
assertEquals(42, result.getNumber());
assertEquals(42F, result.getFraction(), 0F);
assertArrayEquals(new String[] {"Foo", "Bar"}, result.getArray());
assertTrue(result.isBool());
assertArrayEquals(new byte[] {0x1, 0x2}, result.getBytes());
MockHttpOutputMessage outputMessage = new MockHttpOutputMessage();
converter.write(results, baseList.getType(), new MediaType("application", "json"), outputMessage);
JSONAssert.assertEquals(body, outputMessage.getBodyAsString(StandardCharsets.UTF_8), true);
}
@Test
public void read() throws IOException {
InputStream is = getClass().getResourceAsStream("atom.xml");
MockHttpInputMessage inputMessage = new MockHttpInputMessage(is);
inputMessage.getHeaders().setContentType(new MediaType("application", "atom+xml", StandardCharsets.UTF_8));
Feed result = converter.read(Feed.class, inputMessage);
assertEquals("title", result.getTitle());
assertEquals("subtitle", result.getSubtitle().getValue());
List<?> entries = result.getEntries();
assertEquals(2, entries.size());
Entry entry1 = (Entry) entries.get(0);
assertEquals("id1", entry1.getId());
assertEquals("title1", entry1.getTitle());
Entry entry2 = (Entry) entries.get(1);
assertEquals("id2", entry2.getId());
assertEquals("title2", entry2.getTitle());
}
@Test
public void testXmlBomb() throws Exception {
// https://en.wikipedia.org/wiki/Billion_laughs
// https://msdn.microsoft.com/en-us/magazine/ee335713.aspx
String content = "<?xml version=\"1.0\"?>\n" +
"<!DOCTYPE lolz [\n" +
" <!ENTITY lol \"lol\">\n" +
" <!ELEMENT lolz (#PCDATA)>\n" +
" <!ENTITY lol1 \"&lol;&lol;&lol;&lol;&lol;&lol;&lol;&lol;&lol;&lol;\">\n" +
" <!ENTITY lol2 \"&lol1;&lol1;&lol1;&lol1;&lol1;&lol1;&lol1;&lol1;&lol1;&lol1;\">\n" +
" <!ENTITY lol3 \"&lol2;&lol2;&lol2;&lol2;&lol2;&lol2;&lol2;&lol2;&lol2;&lol2;\">\n" +
" <!ENTITY lol4 \"&lol3;&lol3;&lol3;&lol3;&lol3;&lol3;&lol3;&lol3;&lol3;&lol3;\">\n" +
" <!ENTITY lol5 \"&lol4;&lol4;&lol4;&lol4;&lol4;&lol4;&lol4;&lol4;&lol4;&lol4;\">\n" +
" <!ENTITY lol6 \"&lol5;&lol5;&lol5;&lol5;&lol5;&lol5;&lol5;&lol5;&lol5;&lol5;\">\n" +
" <!ENTITY lol7 \"&lol6;&lol6;&lol6;&lol6;&lol6;&lol6;&lol6;&lol6;&lol6;&lol6;\">\n" +
" <!ENTITY lol8 \"&lol7;&lol7;&lol7;&lol7;&lol7;&lol7;&lol7;&lol7;&lol7;&lol7;\">\n" +
" <!ENTITY lol9 \"&lol8;&lol8;&lol8;&lol8;&lol8;&lol8;&lol8;&lol8;&lol8;&lol8;\">\n" +
"]>\n" +
"<rootElement><external>&lol9;</external></rootElement>";
MockHttpInputMessage inputMessage = new MockHttpInputMessage(content.getBytes("UTF-8"));
assertThatExceptionOfType(HttpMessageNotReadableException.class).isThrownBy(() ->
this.converter.read(RootElement.class, inputMessage))
.withMessageContaining("DOCTYPE");
}
@Test
public void readWithTypeMismatchException() throws Exception {
MockHttpInputMessage inputMessage = new MockHttpInputMessage(new byte[0]);
Marshaller marshaller = mock(Marshaller.class);
Unmarshaller unmarshaller = mock(Unmarshaller.class);
given(unmarshaller.unmarshal(isA(StreamSource.class))).willReturn(Integer.valueOf(3));
MarshallingHttpMessageConverter converter = new MarshallingHttpMessageConverter(marshaller, unmarshaller);
try {
converter.read(String.class, inputMessage);
fail("Should have thrown HttpMessageNotReadableException");
}
catch (HttpMessageNotReadableException ex) {
assertTrue(ex.getCause() instanceof TypeMismatchException);
}
}
@Test
public void readWithMarshallingFailureException() throws Exception {
MockHttpInputMessage inputMessage = new MockHttpInputMessage(new byte[0]);
UnmarshallingFailureException ex = new UnmarshallingFailureException("forced");
Unmarshaller unmarshaller = mock(Unmarshaller.class);
given(unmarshaller.unmarshal(isA(StreamSource.class))).willThrow(ex);
MarshallingHttpMessageConverter converter = new MarshallingHttpMessageConverter();
converter.setUnmarshaller(unmarshaller);
try {
converter.read(Object.class, inputMessage);
fail("HttpMessageNotReadableException should be thrown");
}
catch (HttpMessageNotReadableException e) {
assertTrue("Invalid exception hierarchy", e.getCause() == ex);
}
}
@Test
public void readSAXSourceExternal() throws Exception {
MockHttpInputMessage inputMessage = new MockHttpInputMessage(bodyExternal.getBytes("UTF-8"));
inputMessage.getHeaders().setContentType(new MediaType("application", "xml"));
converter.setSupportDtd(true);
SAXSource result = (SAXSource) converter.read(SAXSource.class, inputMessage);
InputSource inputSource = result.getInputSource();
XMLReader reader = result.getXMLReader();
reader.setContentHandler(new DefaultHandler() {
@Override
public void characters(char[] ch, int start, int length) {
String s = new String(ch, start, length);
assertNotEquals("Invalid result", "Foo Bar", s);
}
});
reader.parse(inputSource);
}
@Test
@SuppressWarnings("unchecked")
public void readUntyped() throws IOException {
String body = "{\"bytes\":[1,2],\"array\":[\"Foo\",\"Bar\"]," +
"\"number\":42,\"string\":\"Foo\",\"bool\":true,\"fraction\":42.0}";
MockHttpInputMessage inputMessage = new MockHttpInputMessage(body.getBytes("UTF-8"));
inputMessage.getHeaders().setContentType(new MediaType("application", "json"));
HashMap<String, Object> result = (HashMap<String, Object>) this.converter.read(HashMap.class, inputMessage);
assertEquals("Foo", result.get("string"));
Number n = (Number) result.get("number");
assertEquals(42, n.longValue());
n = (Number) result.get("fraction");
assertEquals(42D, n.doubleValue(), 0D);
List<String> array = new ArrayList<>();
array.add("Foo");
array.add("Bar");
assertEquals(array, result.get("array"));
assertEquals(Boolean.TRUE, result.get("bool"));
byte[] bytes = new byte[2];
List<Number> resultBytes = (ArrayList<Number>)result.get("bytes");
for (int i = 0; i < 2; i++) {
bytes[i] = resultBytes.get(i).byteValue();
}
assertArrayEquals(new byte[] {0x1, 0x2}, bytes);
}
@Test
public void readWithMarshallingFailureException() throws Exception {
MockHttpInputMessage inputMessage = new MockHttpInputMessage(new byte[0]);
UnmarshallingFailureException ex = new UnmarshallingFailureException("forced");
Unmarshaller unmarshaller = mock(Unmarshaller.class);
given(unmarshaller.unmarshal(isA(StreamSource.class))).willThrow(ex);
MarshallingHttpMessageConverter converter = new MarshallingHttpMessageConverter();
converter.setUnmarshaller(unmarshaller);
try {
converter.read(Object.class, inputMessage);
fail("HttpMessageNotReadableException should be thrown");
}
catch (HttpMessageNotReadableException e) {
assertTrue("Invalid exception hierarchy", e.getCause() == ex);
}
}
@Test
public void read() throws IOException {
String body = "<MyBean>" +
"<string>Foo</string>" +
"<number>42</number>" +
"<fraction>42.0</fraction>" +
"<array><array>Foo</array>" +
"<array>Bar</array></array>" +
"<bool>true</bool>" +
"<bytes>AQI=</bytes></MyBean>";
MockHttpInputMessage inputMessage = new MockHttpInputMessage(body.getBytes("UTF-8"));
inputMessage.getHeaders().setContentType(new MediaType("application", "xml"));
MyBean result = (MyBean) converter.read(MyBean.class, inputMessage);
assertEquals("Foo", result.getString());
assertEquals(42, result.getNumber());
assertEquals(42F, result.getFraction(), 0F);
assertArrayEquals(new String[]{"Foo", "Bar"}, result.getArray());
assertTrue(result.isBool());
assertArrayEquals(new byte[]{0x1, 0x2}, result.getBytes());
}
@Test
@SuppressWarnings("unchecked")
public void writeParameterizedBaseType() throws Exception {
ParameterizedTypeReference<List<MyBean>> beansList = new ParameterizedTypeReference<List<MyBean>>() {};
ParameterizedTypeReference<List<MyBase>> baseList = new ParameterizedTypeReference<List<MyBase>>() {};
String body = "[{\"bytes\":[1,2],\"array\":[\"Foo\",\"Bar\"]," +
"\"number\":42,\"string\":\"Foo\",\"bool\":true,\"fraction\":42.0}]";
MockHttpInputMessage inputMessage = new MockHttpInputMessage(body.getBytes(StandardCharsets.UTF_8));
inputMessage.getHeaders().setContentType(new MediaType("application", "json"));
List<MyBean> results = (List<MyBean>) converter.read(beansList.getType(), null, inputMessage);
assertEquals(1, results.size());
MyBean result = results.get(0);
assertEquals("Foo", result.getString());
assertEquals(42, result.getNumber());
assertEquals(42F, result.getFraction(), 0F);
assertArrayEquals(new String[] {"Foo", "Bar"}, result.getArray());
assertTrue(result.isBool());
assertArrayEquals(new byte[] {0x1, 0x2}, result.getBytes());
MockHttpOutputMessage outputMessage = new MockHttpOutputMessage();
converter.write(results, baseList.getType(), new MediaType("application", "json"), outputMessage);
JSONAssert.assertEquals(body, outputMessage.getBodyAsString(StandardCharsets.UTF_8), true);
}
@Test
public void read() throws IOException {
String body = "<MyBean>" +
"<string>Foo</string>" +
"<number>42</number>" +
"<fraction>42.0</fraction>" +
"<array><array>Foo</array>" +
"<array>Bar</array></array>" +
"<bool>true</bool>" +
"<bytes>AQI=</bytes></MyBean>";
MockHttpInputMessage inputMessage = new MockHttpInputMessage(body.getBytes("UTF-8"));
inputMessage.getHeaders().setContentType(new MediaType("application", "xml"));
MyBean result = (MyBean) converter.read(MyBean.class, inputMessage);
assertEquals("Foo", result.getString());
assertEquals(42, result.getNumber());
assertEquals(42F, result.getFraction(), 0F);
assertArrayEquals(new String[]{"Foo", "Bar"}, result.getArray());
assertTrue(result.isBool());
assertArrayEquals(new byte[]{0x1, 0x2}, result.getBytes());
}
@Test
@SuppressWarnings("unchecked")
public void readXmlRootElementExternalEntityEnabled() throws Exception {
Resource external = new ClassPathResource("external.txt", getClass());
String content = "<!DOCTYPE root [" +
" <!ELEMENT external ANY >\n" +
" <!ENTITY ext SYSTEM \"" + external.getURI() + "\" >]>" +
" <list><rootElement><type s=\"1\"/><external>&ext;</external></rootElement></list>";
MockHttpInputMessage inputMessage = new MockHttpInputMessage(content.getBytes("UTF-8"));
Jaxb2CollectionHttpMessageConverter<?> c = new Jaxb2CollectionHttpMessageConverter<Collection<Object>>() {
@Override
protected XMLInputFactory createXmlInputFactory() {
XMLInputFactory inputFactory = XMLInputFactory.newInstance();
inputFactory.setProperty(XMLInputFactory.IS_REPLACING_ENTITY_REFERENCES, true);
return inputFactory;
}
};
Collection<RootElement> result = c.read(rootElementListType, null, inputMessage);
assertEquals(1, result.size());
assertEquals("Foo Bar", result.iterator().next().external);
}
@Test
public void testXmlBomb() throws Exception {
// https://en.wikipedia.org/wiki/Billion_laughs
// https://msdn.microsoft.com/en-us/magazine/ee335713.aspx
String content = "<?xml version=\"1.0\"?>\n" +
"<!DOCTYPE lolz [\n" +
" <!ENTITY lol \"lol\">\n" +
" <!ELEMENT lolz (#PCDATA)>\n" +
" <!ENTITY lol1 \"&lol;&lol;&lol;&lol;&lol;&lol;&lol;&lol;&lol;&lol;\">\n" +
" <!ENTITY lol2 \"&lol1;&lol1;&lol1;&lol1;&lol1;&lol1;&lol1;&lol1;&lol1;&lol1;\">\n" +
" <!ENTITY lol3 \"&lol2;&lol2;&lol2;&lol2;&lol2;&lol2;&lol2;&lol2;&lol2;&lol2;\">\n" +
" <!ENTITY lol4 \"&lol3;&lol3;&lol3;&lol3;&lol3;&lol3;&lol3;&lol3;&lol3;&lol3;\">\n" +
" <!ENTITY lol5 \"&lol4;&lol4;&lol4;&lol4;&lol4;&lol4;&lol4;&lol4;&lol4;&lol4;\">\n" +
" <!ENTITY lol6 \"&lol5;&lol5;&lol5;&lol5;&lol5;&lol5;&lol5;&lol5;&lol5;&lol5;\">\n" +
" <!ENTITY lol7 \"&lol6;&lol6;&lol6;&lol6;&lol6;&lol6;&lol6;&lol6;&lol6;&lol6;\">\n" +
" <!ENTITY lol8 \"&lol7;&lol7;&lol7;&lol7;&lol7;&lol7;&lol7;&lol7;&lol7;&lol7;\">\n" +
" <!ENTITY lol9 \"&lol8;&lol8;&lol8;&lol8;&lol8;&lol8;&lol8;&lol8;&lol8;&lol8;\">\n" +
"]>\n" +
"<list><rootElement><external>&lol9;</external></rootElement></list>";
MockHttpInputMessage inputMessage = new MockHttpInputMessage(content.getBytes("UTF-8"));
assertThatExceptionOfType(HttpMessageNotReadableException.class).isThrownBy(() ->
this.converter.read(this.rootElementListType, null, inputMessage))
.withMessageContaining("\"lol9\"");
}
@Test
@SuppressWarnings("unchecked")
public void readAndWriteGenerics() throws Exception {
Field beansList = ListHolder.class.getField("listField");
String body = "[{\"bytes\":[1,2],\"array\":[\"Foo\",\"Bar\"]," +
"\"number\":42,\"string\":\"Foo\",\"bool\":true,\"fraction\":42.0}]";
MockHttpInputMessage inputMessage = new MockHttpInputMessage(body.getBytes(StandardCharsets.UTF_8));
inputMessage.getHeaders().setContentType(new MediaType("application", "json"));
Type genericType = beansList.getGenericType();
List<MyBean> results = (List<MyBean>) converter.read(genericType, MyBeanListHolder.class, inputMessage);
assertEquals(1, results.size());
MyBean result = results.get(0);
assertEquals("Foo", result.getString());
assertEquals(42, result.getNumber());
assertEquals(42F, result.getFraction(), 0F);
assertArrayEquals(new String[] {"Foo", "Bar"}, result.getArray());
assertTrue(result.isBool());
assertArrayEquals(new byte[] {0x1, 0x2}, result.getBytes());
MockHttpOutputMessage outputMessage = new MockHttpOutputMessage();
converter.write(results, genericType, new MediaType("application", "json"), outputMessage);
JSONAssert.assertEquals(body, outputMessage.getBodyAsString(StandardCharsets.UTF_8), true);
}
@Test
public void readDomSourceWithXmlBomb() throws Exception {
// https://en.wikipedia.org/wiki/Billion_laughs
// https://msdn.microsoft.com/en-us/magazine/ee335713.aspx
String content = "<?xml version=\"1.0\"?>\n" +
"<!DOCTYPE lolz [\n" +
" <!ENTITY lol \"lol\">\n" +
" <!ELEMENT lolz (#PCDATA)>\n" +
" <!ENTITY lol1 \"&lol;&lol;&lol;&lol;&lol;&lol;&lol;&lol;&lol;&lol;\">\n" +
" <!ENTITY lol2 \"&lol1;&lol1;&lol1;&lol1;&lol1;&lol1;&lol1;&lol1;&lol1;&lol1;\">\n" +
" <!ENTITY lol3 \"&lol2;&lol2;&lol2;&lol2;&lol2;&lol2;&lol2;&lol2;&lol2;&lol2;\">\n" +
" <!ENTITY lol4 \"&lol3;&lol3;&lol3;&lol3;&lol3;&lol3;&lol3;&lol3;&lol3;&lol3;\">\n" +
" <!ENTITY lol5 \"&lol4;&lol4;&lol4;&lol4;&lol4;&lol4;&lol4;&lol4;&lol4;&lol4;\">\n" +
" <!ENTITY lol6 \"&lol5;&lol5;&lol5;&lol5;&lol5;&lol5;&lol5;&lol5;&lol5;&lol5;\">\n" +
" <!ENTITY lol7 \"&lol6;&lol6;&lol6;&lol6;&lol6;&lol6;&lol6;&lol6;&lol6;&lol6;\">\n" +
" <!ENTITY lol8 \"&lol7;&lol7;&lol7;&lol7;&lol7;&lol7;&lol7;&lol7;&lol7;&lol7;\">\n" +
" <!ENTITY lol9 \"&lol8;&lol8;&lol8;&lol8;&lol8;&lol8;&lol8;&lol8;&lol8;&lol8;\">\n" +
"]>\n" +
"<root>&lol9;</root>";
MockHttpInputMessage inputMessage = new MockHttpInputMessage(content.getBytes("UTF-8"));
this.thrown.expect(HttpMessageNotReadableException.class);
this.thrown.expectMessage("DOCTYPE");
this.converter.read(DOMSource.class, inputMessage);
}
@Test
public void testXmlBomb() throws Exception {
// https://en.wikipedia.org/wiki/Billion_laughs
// https://msdn.microsoft.com/en-us/magazine/ee335713.aspx
String content = "<?xml version=\"1.0\"?>\n" +
"<!DOCTYPE lolz [\n" +
" <!ENTITY lol \"lol\">\n" +
" <!ELEMENT lolz (#PCDATA)>\n" +
" <!ENTITY lol1 \"&lol;&lol;&lol;&lol;&lol;&lol;&lol;&lol;&lol;&lol;\">\n" +
" <!ENTITY lol2 \"&lol1;&lol1;&lol1;&lol1;&lol1;&lol1;&lol1;&lol1;&lol1;&lol1;\">\n" +
" <!ENTITY lol3 \"&lol2;&lol2;&lol2;&lol2;&lol2;&lol2;&lol2;&lol2;&lol2;&lol2;\">\n" +
" <!ENTITY lol4 \"&lol3;&lol3;&lol3;&lol3;&lol3;&lol3;&lol3;&lol3;&lol3;&lol3;\">\n" +
" <!ENTITY lol5 \"&lol4;&lol4;&lol4;&lol4;&lol4;&lol4;&lol4;&lol4;&lol4;&lol4;\">\n" +
" <!ENTITY lol6 \"&lol5;&lol5;&lol5;&lol5;&lol5;&lol5;&lol5;&lol5;&lol5;&lol5;\">\n" +
" <!ENTITY lol7 \"&lol6;&lol6;&lol6;&lol6;&lol6;&lol6;&lol6;&lol6;&lol6;&lol6;\">\n" +
" <!ENTITY lol8 \"&lol7;&lol7;&lol7;&lol7;&lol7;&lol7;&lol7;&lol7;&lol7;&lol7;\">\n" +
" <!ENTITY lol9 \"&lol8;&lol8;&lol8;&lol8;&lol8;&lol8;&lol8;&lol8;&lol8;&lol8;\">\n" +
"]>\n" +
"<list><rootElement><external>&lol9;</external></rootElement></list>";
MockHttpInputMessage inputMessage = new MockHttpInputMessage(content.getBytes("UTF-8"));
this.thrown.expect(HttpMessageNotReadableException.class);
this.thrown.expectMessage("\"lol9\"");
this.converter.read(this.rootElementListType, null, inputMessage);
}
@Test
public void readWithTypeMismatchException() throws Exception {
MockHttpInputMessage inputMessage = new MockHttpInputMessage(new byte[0]);
Marshaller marshaller = mock(Marshaller.class);
Unmarshaller unmarshaller = mock(Unmarshaller.class);
given(unmarshaller.unmarshal(isA(StreamSource.class))).willReturn(Integer.valueOf(3));
MarshallingHttpMessageConverter converter = new MarshallingHttpMessageConverter(marshaller, unmarshaller);
try {
converter.read(String.class, inputMessage);
fail("Should have thrown HttpMessageNotReadableException");
}
catch (HttpMessageNotReadableException ex) {
assertTrue(ex.getCause() instanceof TypeMismatchException);
}
}
@Test
public void readForm() throws Exception {
String body = "name+1=value+1&name+2=value+2%2B1&name+2=value+2%2B2&name+3";
MockHttpInputMessage inputMessage = new MockHttpInputMessage(body.getBytes(StandardCharsets.ISO_8859_1));
inputMessage.getHeaders().setContentType(
new MediaType("application", "x-www-form-urlencoded", StandardCharsets.ISO_8859_1));
MultiValueMap<String, String> result = this.converter.read(null, inputMessage);
assertEquals("Invalid result", 3, result.size());
assertEquals("Invalid result", "value 1", result.getFirst("name 1"));
List<String> values = result.get("name 2");
assertEquals("Invalid result", 2, values.size());
assertEquals("Invalid result", "value 2+1", values.get(0));
assertEquals("Invalid result", "value 2+2", values.get(1));
assertNull("Invalid result", result.getFirst("name 3"));
}
@Test
@SuppressWarnings("unchecked")
public void readXmlRootElementExternalEntityEnabled() throws Exception {
Resource external = new ClassPathResource("external.txt", getClass());
String content = "<!DOCTYPE root [" +
" <!ELEMENT external ANY >\n" +
" <!ENTITY ext SYSTEM \"" + external.getURI() + "\" >]>" +
" <list><rootElement><type s=\"1\"/><external>&ext;</external></rootElement></list>";
MockHttpInputMessage inputMessage = new MockHttpInputMessage(content.getBytes("UTF-8"));
Jaxb2CollectionHttpMessageConverter<?> c = new Jaxb2CollectionHttpMessageConverter<Collection<Object>>() {
@Override
protected XMLInputFactory createXmlInputFactory() {
XMLInputFactory inputFactory = XMLInputFactory.newInstance();
inputFactory.setProperty(XMLInputFactory.IS_REPLACING_ENTITY_REFERENCES, true);
return inputFactory;
}
};
Collection<RootElement> result = c.read(rootElementListType, null, inputMessage);
assertEquals(1, result.size());
assertEquals("Foo Bar", result.iterator().next().external);
}
@Test
public void testXmlBomb() throws Exception {
// https://en.wikipedia.org/wiki/Billion_laughs
// https://msdn.microsoft.com/en-us/magazine/ee335713.aspx
String content = "<?xml version=\"1.0\"?>\n" +
"<!DOCTYPE lolz [\n" +
" <!ENTITY lol \"lol\">\n" +
" <!ELEMENT lolz (#PCDATA)>\n" +
" <!ENTITY lol1 \"&lol;&lol;&lol;&lol;&lol;&lol;&lol;&lol;&lol;&lol;\">\n" +
" <!ENTITY lol2 \"&lol1;&lol1;&lol1;&lol1;&lol1;&lol1;&lol1;&lol1;&lol1;&lol1;\">\n" +
" <!ENTITY lol3 \"&lol2;&lol2;&lol2;&lol2;&lol2;&lol2;&lol2;&lol2;&lol2;&lol2;\">\n" +
" <!ENTITY lol4 \"&lol3;&lol3;&lol3;&lol3;&lol3;&lol3;&lol3;&lol3;&lol3;&lol3;\">\n" +
" <!ENTITY lol5 \"&lol4;&lol4;&lol4;&lol4;&lol4;&lol4;&lol4;&lol4;&lol4;&lol4;\">\n" +
" <!ENTITY lol6 \"&lol5;&lol5;&lol5;&lol5;&lol5;&lol5;&lol5;&lol5;&lol5;&lol5;\">\n" +
" <!ENTITY lol7 \"&lol6;&lol6;&lol6;&lol6;&lol6;&lol6;&lol6;&lol6;&lol6;&lol6;\">\n" +
" <!ENTITY lol8 \"&lol7;&lol7;&lol7;&lol7;&lol7;&lol7;&lol7;&lol7;&lol7;&lol7;\">\n" +
" <!ENTITY lol9 \"&lol8;&lol8;&lol8;&lol8;&lol8;&lol8;&lol8;&lol8;&lol8;&lol8;\">\n" +
"]>\n" +
"<rootElement><external>&lol9;</external></rootElement>";
MockHttpInputMessage inputMessage = new MockHttpInputMessage(content.getBytes("UTF-8"));
this.thrown.expect(HttpMessageNotReadableException.class);
this.thrown.expectMessage("DOCTYPE");
this.converter.read(RootElement.class, inputMessage);
}
@Test
public void readSAXSourceExternal() throws Exception {
MockHttpInputMessage inputMessage = new MockHttpInputMessage(bodyExternal.getBytes("UTF-8"));
inputMessage.getHeaders().setContentType(new MediaType("application", "xml"));
converter.setSupportDtd(true);
SAXSource result = (SAXSource) converter.read(SAXSource.class, inputMessage);
InputSource inputSource = result.getInputSource();
XMLReader reader = result.getXMLReader();
reader.setContentHandler(new DefaultHandler() {
@Override
public void characters(char[] ch, int start, int length) {
String s = new String(ch, start, length);
assertNotEquals("Invalid result", "Foo Bar", s);
}
});
reader.parse(inputSource);
}
@Test
@SuppressWarnings("unchecked")
public void writeParameterizedBaseType() throws Exception {
ParameterizedTypeReference<List<MyBean>> beansList = new ParameterizedTypeReference<List<MyBean>>() {};
ParameterizedTypeReference<List<MyBase>> baseList = new ParameterizedTypeReference<List<MyBase>>() {};
String body = "[{\"bytes\":[1,2],\"array\":[\"Foo\",\"Bar\"]," +
"\"number\":42,\"string\":\"Foo\",\"bool\":true,\"fraction\":42.0}]";
MockHttpInputMessage inputMessage = new MockHttpInputMessage(body.getBytes(StandardCharsets.UTF_8));
inputMessage.getHeaders().setContentType(new MediaType("application", "json"));
List<MyBean> results = (List<MyBean>) converter.read(beansList.getType(), null, inputMessage);
assertEquals(1, results.size());
MyBean result = results.get(0);
assertEquals("Foo", result.getString());
assertEquals(42, result.getNumber());
assertEquals(42F, result.getFraction(), 0F);
assertArrayEquals(new String[] {"Foo", "Bar"}, result.getArray());
assertTrue(result.isBool());
assertArrayEquals(new byte[] {0x1, 0x2}, result.getBytes());
MockHttpOutputMessage outputMessage = new MockHttpOutputMessage();
converter.write(results, baseList.getType(), new MediaType("application", "json"), outputMessage);
JSONAssert.assertEquals(body, outputMessage.getBodyAsString(StandardCharsets.UTF_8), true);
}