Fix package cycle among http message converters
This change introduces a new AllEncompassingFormHttpMessageConverter class that adds JSON and XML converters for individual mime parts of a multi-part request. The new converter is used in place of the previously used XmlAwareFormHttpMessageConverter. Issue: SPR-10055
This commit is contained in:
parent
d309bb4bbb
commit
85a552daed
|
|
@ -36,15 +36,11 @@ import org.springframework.http.HttpHeaders;
|
|||
import org.springframework.http.HttpInputMessage;
|
||||
import org.springframework.http.HttpOutputMessage;
|
||||
import org.springframework.http.MediaType;
|
||||
import org.springframework.http.converter.json.MappingJackson2HttpMessageConverter;
|
||||
import org.springframework.http.converter.json.MappingJacksonHttpMessageConverter;
|
||||
import org.springframework.util.Assert;
|
||||
import org.springframework.util.ClassUtils;
|
||||
import org.springframework.util.FileCopyUtils;
|
||||
import org.springframework.util.LinkedMultiValueMap;
|
||||
import org.springframework.util.MultiValueMap;
|
||||
import org.springframework.util.StringUtils;
|
||||
import org.springframework.web.client.RestTemplate;
|
||||
|
||||
/**
|
||||
* Implementation of {@link HttpMessageConverter} that can handle form data, including multipart form data (i.e. file
|
||||
|
|
@ -76,14 +72,6 @@ import org.springframework.web.client.RestTemplate;
|
|||
*/
|
||||
public class FormHttpMessageConverter implements HttpMessageConverter<MultiValueMap<String, ?>> {
|
||||
|
||||
private static final boolean jackson2Present =
|
||||
ClassUtils.isPresent("com.fasterxml.jackson.databind.ObjectMapper", RestTemplate.class.getClassLoader()) &&
|
||||
ClassUtils.isPresent("com.fasterxml.jackson.core.JsonGenerator", RestTemplate.class.getClassLoader());
|
||||
|
||||
private static final boolean jacksonPresent =
|
||||
ClassUtils.isPresent("org.codehaus.jackson.map.ObjectMapper", RestTemplate.class.getClassLoader()) &&
|
||||
ClassUtils.isPresent("org.codehaus.jackson.JsonGenerator", RestTemplate.class.getClassLoader());
|
||||
|
||||
private static final byte[] BOUNDARY_CHARS =
|
||||
new byte[]{'-', '_', '1', '2', '3', '4', '5', '6', '7', '8', '9', '0', 'a', 'b', 'c', 'd', 'e', 'f', 'g',
|
||||
'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z', 'A',
|
||||
|
|
@ -108,12 +96,6 @@ public class FormHttpMessageConverter implements HttpMessageConverter<MultiValue
|
|||
stringHttpMessageConverter.setWriteAcceptCharset(false);
|
||||
this.partConverters.add(stringHttpMessageConverter);
|
||||
this.partConverters.add(new ResourceHttpMessageConverter());
|
||||
if (jackson2Present) {
|
||||
this.partConverters.add(new MappingJackson2HttpMessageConverter());
|
||||
}
|
||||
else if (jacksonPresent) {
|
||||
this.partConverters.add(new MappingJacksonHttpMessageConverter());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -0,0 +1,59 @@
|
|||
/*
|
||||
* Copyright 2002-2012 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.springframework.http.converter.support;
|
||||
|
||||
import org.springframework.http.converter.FormHttpMessageConverter;
|
||||
import org.springframework.http.converter.json.MappingJackson2HttpMessageConverter;
|
||||
import org.springframework.http.converter.json.MappingJacksonHttpMessageConverter;
|
||||
import org.springframework.http.converter.xml.Jaxb2RootElementHttpMessageConverter;
|
||||
import org.springframework.http.converter.xml.SourceHttpMessageConverter;
|
||||
import org.springframework.util.ClassUtils;
|
||||
|
||||
/**
|
||||
* Extension of {@link org.springframework.http.converter.FormHttpMessageConverter},
|
||||
* adding support for XML and JSON-based parts.
|
||||
*
|
||||
* @author Rossen Stoyanchev
|
||||
* @since 3.2
|
||||
*/
|
||||
public class AllEncompassingFormHttpMessageConverter extends FormHttpMessageConverter {
|
||||
|
||||
private static final boolean jackson2Present =
|
||||
ClassUtils.isPresent("com.fasterxml.jackson.databind.ObjectMapper", AllEncompassingFormHttpMessageConverter.class.getClassLoader()) &&
|
||||
ClassUtils.isPresent("com.fasterxml.jackson.core.JsonGenerator", AllEncompassingFormHttpMessageConverter.class.getClassLoader());
|
||||
|
||||
private static final boolean jacksonPresent =
|
||||
ClassUtils.isPresent("org.codehaus.jackson.map.ObjectMapper", AllEncompassingFormHttpMessageConverter.class.getClassLoader()) &&
|
||||
ClassUtils.isPresent("org.codehaus.jackson.JsonGenerator", AllEncompassingFormHttpMessageConverter.class.getClassLoader());
|
||||
|
||||
private static final boolean jaxb2Present =
|
||||
ClassUtils.isPresent("javax.xml.bind.Binder", AllEncompassingFormHttpMessageConverter.class.getClassLoader());
|
||||
|
||||
|
||||
public AllEncompassingFormHttpMessageConverter() {
|
||||
addPartConverter(new SourceHttpMessageConverter());
|
||||
if (jaxb2Present) {
|
||||
addPartConverter(new Jaxb2RootElementHttpMessageConverter());
|
||||
}
|
||||
if (jackson2Present) {
|
||||
addPartConverter(new MappingJackson2HttpMessageConverter());
|
||||
}
|
||||
else if (jacksonPresent) {
|
||||
addPartConverter(new MappingJacksonHttpMessageConverter());
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -17,6 +17,7 @@
|
|||
package org.springframework.http.converter.xml;
|
||||
|
||||
import org.springframework.http.converter.FormHttpMessageConverter;
|
||||
import org.springframework.http.converter.support.AllEncompassingFormHttpMessageConverter;
|
||||
|
||||
/**
|
||||
* Extension of {@link org.springframework.http.converter.FormHttpMessageConverter},
|
||||
|
|
@ -24,6 +25,7 @@ import org.springframework.http.converter.FormHttpMessageConverter;
|
|||
*
|
||||
* @author Juergen Hoeller
|
||||
* @since 3.0.3
|
||||
* @deprecated in favor of {@link AllEncompassingFormHttpMessageConverter}
|
||||
*/
|
||||
public class XmlAwareFormHttpMessageConverter extends FormHttpMessageConverter {
|
||||
|
||||
|
|
|
|||
|
|
@ -45,6 +45,7 @@ import org.springframework.http.converter.feed.AtomFeedHttpMessageConverter;
|
|||
import org.springframework.http.converter.feed.RssChannelHttpMessageConverter;
|
||||
import org.springframework.http.converter.json.MappingJackson2HttpMessageConverter;
|
||||
import org.springframework.http.converter.json.MappingJacksonHttpMessageConverter;
|
||||
import org.springframework.http.converter.support.AllEncompassingFormHttpMessageConverter;
|
||||
import org.springframework.http.converter.xml.Jaxb2RootElementHttpMessageConverter;
|
||||
import org.springframework.http.converter.xml.SourceHttpMessageConverter;
|
||||
import org.springframework.http.converter.xml.XmlAwareFormHttpMessageConverter;
|
||||
|
|
@ -151,7 +152,7 @@ public class RestTemplate extends InterceptingHttpAccessor implements RestOperat
|
|||
this.messageConverters.add(new StringHttpMessageConverter());
|
||||
this.messageConverters.add(new ResourceHttpMessageConverter());
|
||||
this.messageConverters.add(new SourceHttpMessageConverter());
|
||||
this.messageConverters.add(new XmlAwareFormHttpMessageConverter());
|
||||
this.messageConverters.add(new AllEncompassingFormHttpMessageConverter());
|
||||
if (romePresent) {
|
||||
this.messageConverters.add(new AtomFeedHttpMessageConverter());
|
||||
this.messageConverters.add(new RssChannelHttpMessageConverter());
|
||||
|
|
|
|||
|
|
@ -38,6 +38,7 @@ import javax.servlet.http.HttpServletResponse;
|
|||
import org.springframework.http.HttpInputMessage;
|
||||
import org.springframework.http.MediaType;
|
||||
import org.springframework.http.converter.FormHttpMessageConverter;
|
||||
import org.springframework.http.converter.support.AllEncompassingFormHttpMessageConverter;
|
||||
import org.springframework.http.converter.xml.XmlAwareFormHttpMessageConverter;
|
||||
import org.springframework.http.server.ServletServerHttpRequest;
|
||||
import org.springframework.util.LinkedMultiValueMap;
|
||||
|
|
@ -60,7 +61,7 @@ import org.springframework.util.MultiValueMap;
|
|||
*/
|
||||
public class HttpPutFormContentFilter extends OncePerRequestFilter {
|
||||
|
||||
private final FormHttpMessageConverter formConverter = new XmlAwareFormHttpMessageConverter();
|
||||
private final FormHttpMessageConverter formConverter = new AllEncompassingFormHttpMessageConverter();
|
||||
|
||||
/**
|
||||
* The default character set to use for reading form data.
|
||||
|
|
|
|||
|
|
@ -40,6 +40,7 @@ import org.springframework.http.HttpHeaders;
|
|||
import org.springframework.http.MediaType;
|
||||
import org.springframework.http.MockHttpInputMessage;
|
||||
import org.springframework.http.MockHttpOutputMessage;
|
||||
import org.springframework.http.converter.support.AllEncompassingFormHttpMessageConverter;
|
||||
import org.springframework.http.converter.xml.XmlAwareFormHttpMessageConverter;
|
||||
import org.springframework.util.LinkedMultiValueMap;
|
||||
import org.springframework.util.MultiValueMap;
|
||||
|
|
@ -55,7 +56,7 @@ public class FormHttpMessageConverterTests {
|
|||
|
||||
@Before
|
||||
public void setUp() {
|
||||
converter = new XmlAwareFormHttpMessageConverter();
|
||||
converter = new AllEncompassingFormHttpMessageConverter();
|
||||
}
|
||||
|
||||
@Test
|
||||
|
|
|
|||
|
|
@ -39,6 +39,7 @@ import org.springframework.http.converter.feed.AtomFeedHttpMessageConverter;
|
|||
import org.springframework.http.converter.feed.RssChannelHttpMessageConverter;
|
||||
import org.springframework.http.converter.json.MappingJackson2HttpMessageConverter;
|
||||
import org.springframework.http.converter.json.MappingJacksonHttpMessageConverter;
|
||||
import org.springframework.http.converter.support.AllEncompassingFormHttpMessageConverter;
|
||||
import org.springframework.http.converter.xml.Jaxb2RootElementHttpMessageConverter;
|
||||
import org.springframework.http.converter.xml.SourceHttpMessageConverter;
|
||||
import org.springframework.http.converter.xml.XmlAwareFormHttpMessageConverter;
|
||||
|
|
@ -413,7 +414,7 @@ class AnnotationDrivenBeanDefinitionParser implements BeanDefinitionParser {
|
|||
|
||||
messageConverters.add(createConverterBeanDefinition(ResourceHttpMessageConverter.class, source));
|
||||
messageConverters.add(createConverterBeanDefinition(SourceHttpMessageConverter.class, source));
|
||||
messageConverters.add(createConverterBeanDefinition(XmlAwareFormHttpMessageConverter.class, source));
|
||||
messageConverters.add(createConverterBeanDefinition(AllEncompassingFormHttpMessageConverter.class, source));
|
||||
if (romePresent) {
|
||||
messageConverters.add(createConverterBeanDefinition(AtomFeedHttpMessageConverter.class, source));
|
||||
messageConverters.add(createConverterBeanDefinition(RssChannelHttpMessageConverter.class, source));
|
||||
|
|
|
|||
|
|
@ -46,6 +46,7 @@ import org.springframework.http.converter.feed.AtomFeedHttpMessageConverter;
|
|||
import org.springframework.http.converter.feed.RssChannelHttpMessageConverter;
|
||||
import org.springframework.http.converter.json.MappingJackson2HttpMessageConverter;
|
||||
import org.springframework.http.converter.json.MappingJacksonHttpMessageConverter;
|
||||
import org.springframework.http.converter.support.AllEncompassingFormHttpMessageConverter;
|
||||
import org.springframework.http.converter.xml.Jaxb2RootElementHttpMessageConverter;
|
||||
import org.springframework.http.converter.xml.SourceHttpMessageConverter;
|
||||
import org.springframework.http.converter.xml.XmlAwareFormHttpMessageConverter;
|
||||
|
|
@ -531,7 +532,7 @@ public class WebMvcConfigurationSupport implements ApplicationContextAware, Serv
|
|||
messageConverters.add(stringConverter);
|
||||
messageConverters.add(new ResourceHttpMessageConverter());
|
||||
messageConverters.add(new SourceHttpMessageConverter<Source>());
|
||||
messageConverters.add(new XmlAwareFormHttpMessageConverter());
|
||||
messageConverters.add(new AllEncompassingFormHttpMessageConverter());
|
||||
if (romePresent) {
|
||||
messageConverters.add(new AtomFeedHttpMessageConverter());
|
||||
messageConverters.add(new RssChannelHttpMessageConverter());
|
||||
|
|
|
|||
|
|
@ -37,6 +37,7 @@ import org.springframework.core.OrderComparator;
|
|||
import org.springframework.http.converter.ByteArrayHttpMessageConverter;
|
||||
import org.springframework.http.converter.HttpMessageConverter;
|
||||
import org.springframework.http.converter.StringHttpMessageConverter;
|
||||
import org.springframework.http.converter.support.AllEncompassingFormHttpMessageConverter;
|
||||
import org.springframework.http.converter.xml.SourceHttpMessageConverter;
|
||||
import org.springframework.http.converter.xml.XmlAwareFormHttpMessageConverter;
|
||||
import org.springframework.web.accept.ContentNegotiationManager;
|
||||
|
|
@ -104,7 +105,7 @@ public class ExceptionHandlerExceptionResolver extends AbstractHandlerMethodExce
|
|||
this.messageConverters.add(new ByteArrayHttpMessageConverter());
|
||||
this.messageConverters.add(stringHttpMessageConverter);
|
||||
this.messageConverters.add(new SourceHttpMessageConverter<Source>());
|
||||
this.messageConverters.add(new XmlAwareFormHttpMessageConverter());
|
||||
this.messageConverters.add(new AllEncompassingFormHttpMessageConverter());
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -45,6 +45,7 @@ import org.springframework.core.task.SimpleAsyncTaskExecutor;
|
|||
import org.springframework.http.converter.ByteArrayHttpMessageConverter;
|
||||
import org.springframework.http.converter.HttpMessageConverter;
|
||||
import org.springframework.http.converter.StringHttpMessageConverter;
|
||||
import org.springframework.http.converter.support.AllEncompassingFormHttpMessageConverter;
|
||||
import org.springframework.http.converter.xml.SourceHttpMessageConverter;
|
||||
import org.springframework.http.converter.xml.XmlAwareFormHttpMessageConverter;
|
||||
import org.springframework.ui.ModelMap;
|
||||
|
|
@ -181,7 +182,7 @@ public class RequestMappingHandlerAdapter extends AbstractHandlerMethodAdapter i
|
|||
this.messageConverters.add(new ByteArrayHttpMessageConverter());
|
||||
this.messageConverters.add(stringHttpMessageConverter);
|
||||
this.messageConverters.add(new SourceHttpMessageConverter<Source>());
|
||||
this.messageConverters.add(new XmlAwareFormHttpMessageConverter());
|
||||
this.messageConverters.add(new AllEncompassingFormHttpMessageConverter());
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -41,6 +41,7 @@ import org.springframework.http.client.HttpComponentsClientHttpRequestFactory;
|
|||
import org.springframework.http.converter.HttpMessageConverter;
|
||||
import org.springframework.http.converter.ResourceHttpMessageConverter;
|
||||
import org.springframework.http.converter.json.MappingJacksonHttpMessageConverter;
|
||||
import org.springframework.http.converter.support.AllEncompassingFormHttpMessageConverter;
|
||||
import org.springframework.http.converter.xml.XmlAwareFormHttpMessageConverter;
|
||||
import org.springframework.stereotype.Controller;
|
||||
import org.springframework.util.LinkedMultiValueMap;
|
||||
|
|
@ -102,7 +103,7 @@ public class RequestPartIntegrationTests {
|
|||
|
||||
@Before
|
||||
public void setUp() {
|
||||
XmlAwareFormHttpMessageConverter converter = new XmlAwareFormHttpMessageConverter();
|
||||
AllEncompassingFormHttpMessageConverter converter = new AllEncompassingFormHttpMessageConverter();
|
||||
converter.setPartConverters(Arrays.<HttpMessageConverter<?>>asList(
|
||||
new ResourceHttpMessageConverter(), new MappingJacksonHttpMessageConverter()));
|
||||
|
||||
|
|
|
|||
|
|
@ -32,6 +32,7 @@ import org.springframework.http.converter.ByteArrayHttpMessageConverter;
|
|||
import org.springframework.http.converter.HttpMessageConverter;
|
||||
import org.springframework.http.converter.StringHttpMessageConverter;
|
||||
import org.springframework.http.converter.json.MappingJackson2HttpMessageConverter;
|
||||
import org.springframework.http.converter.support.AllEncompassingFormHttpMessageConverter;
|
||||
import org.springframework.http.converter.xml.XmlAwareFormHttpMessageConverter;
|
||||
import org.springframework.mock.web.test.MockHttpServletRequest;
|
||||
import org.springframework.mock.web.test.MockHttpServletResponse;
|
||||
|
|
@ -119,7 +120,7 @@ public class RequestResponseBodyMethodProcessorTests {
|
|||
this.servletRequest.setContentType(MediaType.APPLICATION_FORM_URLENCODED_VALUE);
|
||||
|
||||
List<HttpMessageConverter<?>> converters = new ArrayList<HttpMessageConverter<?>>();
|
||||
converters.add(new XmlAwareFormHttpMessageConverter());
|
||||
converters.add(new AllEncompassingFormHttpMessageConverter());
|
||||
RequestResponseBodyMethodProcessor processor = new RequestResponseBodyMethodProcessor(converters);
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
|
|
|
|||
|
|
@ -105,7 +105,7 @@ Changes in version 3.2 RC1 (2012-11-04)
|
|||
* use concurrent cache to improve performance of GenericTypeResolver (SPR-8701)
|
||||
* cache and late resolve annotations on bean properties to improve performance (SPR-9166)
|
||||
* allow PropertyResolver implementations to ignore unresolvable ${placeholders} (SPR-9569)
|
||||
* FormHttpMessageConverter now adds Jackson JSON converters if available on the classpath (SPR-10055)
|
||||
* AllEncompassingFormHttpMessageConverter now adds XML/JSON converters for individual mime parts (SPR-10055)
|
||||
|
||||
Changes in version 3.2 M2 (2012-09-11)
|
||||
--------------------------------------
|
||||
|
|
|
|||
Loading…
Reference in New Issue