diff --git a/spring-web/src/main/java/org/springframework/http/converter/support/AllEncompassingFormHttpMessageConverter.java b/spring-web/src/main/java/org/springframework/http/converter/support/AllEncompassingFormHttpMessageConverter.java index 19a49a9e8d4..d93e6ff1e79 100644 --- a/spring-web/src/main/java/org/springframework/http/converter/support/AllEncompassingFormHttpMessageConverter.java +++ b/spring-web/src/main/java/org/springframework/http/converter/support/AllEncompassingFormHttpMessageConverter.java @@ -53,10 +53,7 @@ public class AllEncompassingFormHttpMessageConverter extends FormHttpMessageConv public AllEncompassingFormHttpMessageConverter() { addPartConverter(new SourceHttpMessageConverter()); - if (jackson2XmlPresent) { - addPartConverter(new MappingJackson2XmlHttpMessageConverter()); - } - else if (jaxb2Present) { + if (jaxb2Present && !jackson2Present) { addPartConverter(new Jaxb2RootElementHttpMessageConverter()); } @@ -66,6 +63,10 @@ public class AllEncompassingFormHttpMessageConverter extends FormHttpMessageConv else if (gsonPresent) { addPartConverter(new GsonHttpMessageConverter()); } + + if (jackson2XmlPresent) { + addPartConverter(new MappingJackson2XmlHttpMessageConverter()); + } } } diff --git a/spring-web/src/test/java/org/springframework/http/converter/FormHttpMessageConverterTests.java b/spring-web/src/test/java/org/springframework/http/converter/FormHttpMessageConverterTests.java index 7ec753a2734..3d36c70fa6f 100644 --- a/spring-web/src/test/java/org/springframework/http/converter/FormHttpMessageConverterTests.java +++ b/spring-web/src/test/java/org/springframework/http/converter/FormHttpMessageConverterTests.java @@ -22,6 +22,8 @@ import java.io.InputStream; import java.io.StringReader; import java.nio.charset.Charset; import java.util.List; +import javax.xml.bind.annotation.XmlElement; +import javax.xml.bind.annotation.XmlRootElement; import javax.xml.transform.Source; import javax.xml.transform.stream.StreamSource; @@ -198,6 +200,47 @@ public class FormHttpMessageConverterTests { verify(outputMessage.getBody(), never()).close(); } + // SPR-13309 + + @Test + public void writeMultipartOrder() throws Exception { + MyBean myBean = new MyBean(); + myBean.setString("foo"); + + MultiValueMap parts = new LinkedMultiValueMap(); + parts.add("part1", myBean); + + HttpHeaders entityHeaders = new HttpHeaders(); + entityHeaders.setContentType(MediaType.TEXT_XML); + HttpEntity entity = new HttpEntity(myBean, entityHeaders); + parts.add("part2", entity); + + MockHttpOutputMessage outputMessage = new MockHttpOutputMessage(); + this.converter.setMultipartCharset(UTF_8); + this.converter.write(parts, new MediaType("multipart", "form-data", UTF_8), outputMessage); + + final MediaType contentType = outputMessage.getHeaders().getContentType(); + assertNotNull("No boundary found", contentType.getParameter("boundary")); + + // see if Commons FileUpload can read what we wrote + FileItemFactory fileItemFactory = new DiskFileItemFactory(); + FileUpload fileUpload = new FileUpload(fileItemFactory); + RequestContext requestContext = new MockHttpOutputMessageRequestContext(outputMessage); + List items = fileUpload.parseRequest(requestContext); + assertEquals(2, items.size()); + + FileItem item = items.get(0); + assertTrue(item.isFormField()); + assertEquals("part1", item.getFieldName()); + assertEquals("{\"string\":\"foo\"}", item.getString()); + + item = items.get(1); + assertTrue(item.isFormField()); + assertEquals("part2", item.getFieldName()); + assertEquals("foo", item.getString()); + } + + private static class MockHttpOutputMessageRequestContext implements RequestContext { @@ -233,4 +276,17 @@ public class FormHttpMessageConverterTests { } } + public static class MyBean { + + private String string; + + public String getString() { + return this.string; + } + + public void setString(String string) { + this.string = string; + } + } + }