Add Jackson 2 HttpMessageConverter and View
Jackson 2 uses completely new package names and new maven artifact ids.
This change adds Jackson 2 as an optional dependency and also provides
MappingJackson2HttpMessageConverter and MappingJackson2JsonView for use
with the new version.
The MVC namespace and the MVC Java config detect and use
MappingJackson2HttpMessageConverter if Jackson 2 is present.
Otherwise if Jackson 1.x is present,
then MappingJacksonHttpMessageConverter is used.
Issue: SPR-9302
Backport-Issue: SPR-9507
Backport-Commit: e63ca04fdb
This commit is contained in:
@@ -28,6 +28,9 @@
|
||||
<classpathentry kind="var" path="IVY_CACHE/org.apache.taglibs/com.springsource.org.apache.taglibs.standard/1.1.2/com.springsource.org.apache.taglibs.standard-1.1.2.jar" sourcepath="/IVY_CACHE/org.apache.taglibs/com.springsource.org.apache.taglibs.standard/1.1.2/com.springsource.org.apache.taglibs.standard-sources-1.1.2.jar"/>
|
||||
<classpathentry kind="var" path="IVY_CACHE/org.codehaus.jackson/com.springsource.org.codehaus.jackson.mapper/1.4.2/com.springsource.org.codehaus.jackson.mapper-1.4.2.jar" sourcepath="/IVY_CACHE/org.codehaus.jackson/com.springsource.org.codehaus.jackson.mapper/1.4.2/com.springsource.org.codehaus.jackson.mapper-sources-1.4.2.jar"/>
|
||||
<classpathentry kind="var" path="IVY_CACHE/org.codehaus.jackson/com.springsource.org.codehaus.jackson/1.4.2/com.springsource.org.codehaus.jackson-1.4.2.jar" sourcepath="/IVY_CACHE/org.codehaus.jackson/com.springsource.org.codehaus.jackson/1.4.2/com.springsource.org.codehaus.jackson-sources-1.4.2.jar"/>
|
||||
<classpathentry kind="var" path="IVY_CACHE/com.fasterxml.jackson.core/com.springsource.com.fasterxml.jackson.core.jackson-databind/2.0.2/com.springsource.com.fasterxml.jackson.core.jackson-databind-2.0.2.jar" sourcepath="IVY_CACHE/com.fasterxml.jackson.core/com.springsource.com.fasterxml.jackson.core.jackson-databind/2.0.2/com.springsource.com.fasterxml.jackson.core.jackson-databind-2.0.2-sources.jar"/>
|
||||
<classpathentry kind="var" path="IVY_CACHE/com.fasterxml.jackson.core/com.springsource.com.fasterxml.jackson.core.jackson-core/2.0.2/com.springsource.com.fasterxml.jackson.core.jackson-core-2.0.2.jar" sourcepath="IVY_CACHE/com.fasterxml.jackson.core/com.springsource.com.fasterxml.jackson.core.jackson-core/2.0.2/com.springsource.com.fasterxml.jackson.core.jackson-core-2.0.2-sources.jar"/>
|
||||
<classpathentry kind="var" path="IVY_CACHE/com.fasterxml.jackson.core/com.springsource.com.fasterxml.jackson.core.jackson-annotations/2.0.2/com.springsource.com.fasterxml.jackson.core.jackson-annotations-2.0.2.jar" sourcepath="IVY_CACHE/com.fasterxml.jackson.core/com.springsource.com.fasterxml.jackson.core.jackson-annotations/2.0.2/com.springsource.com.fasterxml.jackson.core.jackson-annotations-2.0.2-sources.jar"/>
|
||||
<classpathentry kind="var" path="IVY_CACHE/org.custommonkey.xmlunit/com.springsource.org.custommonkey.xmlunit/1.2.0/com.springsource.org.custommonkey.xmlunit-1.2.0.jar" sourcepath="/IVY_CACHE/org.custommonkey.xmlunit/com.springsource.org.custommonkey.xmlunit/1.2.0/com.springsource.org.custommonkey.xmlunit-sources-1.2.0.jar"/>
|
||||
<classpathentry kind="var" path="IVY_CACHE/org.easymock/com.springsource.org.easymock/2.5.1/com.springsource.org.easymock-2.5.1.jar" sourcepath="/IVY_CACHE/org.easymock/com.springsource.org.easymock/2.5.1/com.springsource.org.easymock-sources-2.5.1.jar"/>
|
||||
<classpathentry kind="var" path="IVY_CACHE/org.jdom/com.springsource.org.jdom/1.1.0/com.springsource.org.jdom-1.1.0.jar"/>
|
||||
|
||||
@@ -64,9 +64,11 @@
|
||||
conf="optional, httpclient->compile"/>
|
||||
<dependency org="org.apache.log4j" name="com.springsource.org.apache.log4j" rev="1.2.15"
|
||||
conf="optional, log4j->compile"/>
|
||||
<dependency org="org.codehaus.jackson" name="com.springsource.org.codehaus.jackson.mapper" rev="1.4.2"
|
||||
<dependency org="org.codehaus.jackson" name="com.springsource.org.codehaus.jackson.mapper" rev="1.4.2"
|
||||
conf="optional, jackson->compile"/>
|
||||
<dependency org="org.jdom" name="com.springsource.org.jdom" rev="1.1.0"
|
||||
<dependency org="com.fasterxml.jackson.core" name="com.springsource.com.fasterxml.jackson.core.jackson-databind" rev="2.0.2"
|
||||
conf="optional, jackson->compile"/>
|
||||
<dependency org="org.jdom" name="com.springsource.org.jdom" rev="1.1.0"
|
||||
conf="optional, feed->compile"/>
|
||||
<dependency org="org.springframework" name="org.springframework.aop" rev="latest.integration"
|
||||
conf="compile->compile"/>
|
||||
|
||||
@@ -124,6 +124,12 @@
|
||||
<version>1.4.2</version>
|
||||
<optional>true</optional>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.fasterxml.jackson.core</groupId>
|
||||
<artifactId>jackson-databind</artifactId>
|
||||
<version>2.0.2</version>
|
||||
<optional>true</optional>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework</groupId>
|
||||
<artifactId>spring-aop</artifactId>
|
||||
|
||||
@@ -0,0 +1,188 @@
|
||||
/*
|
||||
* 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.json;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.nio.charset.Charset;
|
||||
import java.util.List;
|
||||
|
||||
import org.springframework.http.HttpInputMessage;
|
||||
import org.springframework.http.HttpOutputMessage;
|
||||
import org.springframework.http.MediaType;
|
||||
import org.springframework.http.converter.AbstractHttpMessageConverter;
|
||||
import org.springframework.http.converter.HttpMessageNotReadableException;
|
||||
import org.springframework.http.converter.HttpMessageNotWritableException;
|
||||
import org.springframework.util.Assert;
|
||||
|
||||
import com.fasterxml.jackson.core.JsonEncoding;
|
||||
import com.fasterxml.jackson.core.JsonGenerator;
|
||||
import com.fasterxml.jackson.core.JsonProcessingException;
|
||||
import com.fasterxml.jackson.databind.JavaType;
|
||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
|
||||
/**
|
||||
* Implementation of {@link org.springframework.http.converter.HttpMessageConverter HttpMessageConverter}
|
||||
* that can read and write JSON using <a href="http://jackson.codehaus.org/">Jackson 2's</a> {@link ObjectMapper}.
|
||||
*
|
||||
* <p>This converter can be used to bind to typed beans, or untyped {@link java.util.HashMap HashMap} instances.
|
||||
*
|
||||
* <p>By default, this converter supports {@code application/json}. This can be overridden by setting the
|
||||
* {@link #setSupportedMediaTypes(List) supportedMediaTypes} property.
|
||||
*
|
||||
* @author Arjen Poutsma
|
||||
* @author Keith Donald
|
||||
* @since 3.2
|
||||
* @see org.springframework.web.servlet.view.json.MappingJackson2JsonView
|
||||
*/
|
||||
public class MappingJackson2HttpMessageConverter extends AbstractHttpMessageConverter<Object> {
|
||||
|
||||
public static final Charset DEFAULT_CHARSET = Charset.forName("UTF-8");
|
||||
|
||||
|
||||
private ObjectMapper objectMapper = new ObjectMapper();
|
||||
|
||||
private boolean prefixJson = false;
|
||||
|
||||
|
||||
/**
|
||||
* Construct a new {@code BindingJacksonHttpMessageConverter}.
|
||||
*/
|
||||
public MappingJackson2HttpMessageConverter() {
|
||||
super(new MediaType("application", "json", DEFAULT_CHARSET));
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the {@code ObjectMapper} for this view. If not set, a default
|
||||
* {@link ObjectMapper#ObjectMapper() ObjectMapper} is used.
|
||||
* <p>Setting a custom-configured {@code ObjectMapper} is one way to take further control of the JSON
|
||||
* serialization process. For example, an extended {@link org.codehaus.jackson.map.SerializerFactory}
|
||||
* can be configured that provides custom serializers for specific types. The other option for refining
|
||||
* the serialization process is to use Jackson's provided annotations on the types to be serialized,
|
||||
* in which case a custom-configured ObjectMapper is unnecessary.
|
||||
*/
|
||||
public void setObjectMapper(ObjectMapper objectMapper) {
|
||||
Assert.notNull(objectMapper, "ObjectMapper must not be null");
|
||||
this.objectMapper = objectMapper;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the underlying {@code ObjectMapper} for this view.
|
||||
*/
|
||||
public ObjectMapper getObjectMapper() {
|
||||
return this.objectMapper;
|
||||
}
|
||||
|
||||
/**
|
||||
* Indicate whether the JSON output by this view should be prefixed with "{} &&". Default is false.
|
||||
* <p>Prefixing the JSON string in this manner is used to help prevent JSON Hijacking.
|
||||
* The prefix renders the string syntactically invalid as a script so that it cannot be hijacked.
|
||||
* This prefix does not affect the evaluation of JSON, but if JSON validation is performed on the
|
||||
* string, the prefix would need to be ignored.
|
||||
*/
|
||||
public void setPrefixJson(boolean prefixJson) {
|
||||
this.prefixJson = prefixJson;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public boolean canRead(Class<?> clazz, MediaType mediaType) {
|
||||
JavaType javaType = getJavaType(clazz);
|
||||
return (this.objectMapper.canDeserialize(javaType) && canRead(mediaType));
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean canWrite(Class<?> clazz, MediaType mediaType) {
|
||||
return (this.objectMapper.canSerialize(clazz) && canWrite(mediaType));
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean supports(Class<?> clazz) {
|
||||
// should not be called, since we override canRead/Write instead
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Object readInternal(Class<?> clazz, HttpInputMessage inputMessage)
|
||||
throws IOException, HttpMessageNotReadableException {
|
||||
|
||||
JavaType javaType = getJavaType(clazz);
|
||||
try {
|
||||
return this.objectMapper.readValue(inputMessage.getBody(), javaType);
|
||||
}
|
||||
catch (JsonProcessingException ex) {
|
||||
throw new HttpMessageNotReadableException("Could not read JSON: " + ex.getMessage(), ex);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void writeInternal(Object object, HttpOutputMessage outputMessage)
|
||||
throws IOException, HttpMessageNotWritableException {
|
||||
|
||||
JsonEncoding encoding = getJsonEncoding(outputMessage.getHeaders().getContentType());
|
||||
JsonGenerator jsonGenerator =
|
||||
this.objectMapper.getJsonFactory().createJsonGenerator(outputMessage.getBody(), encoding);
|
||||
try {
|
||||
if (this.prefixJson) {
|
||||
jsonGenerator.writeRaw("{} && ");
|
||||
}
|
||||
this.objectMapper.writeValue(jsonGenerator, object);
|
||||
}
|
||||
catch (JsonProcessingException ex) {
|
||||
throw new HttpMessageNotWritableException("Could not write JSON: " + ex.getMessage(), ex);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Return the Jackson {@link JavaType} for the specified class.
|
||||
* <p>The default implementation returns {@link ObjectMapper#constructType(java.lang.reflect.Type)},
|
||||
* but this can be overridden in subclasses, to allow for custom generic collection handling.
|
||||
* For instance:
|
||||
* <pre class="code">
|
||||
* protected JavaType getJavaType(Class<?> clazz) {
|
||||
* if (List.class.isAssignableFrom(clazz)) {
|
||||
* return objectMapper.getTypeFactory().constructCollectionType(ArrayList.class, MyBean.class);
|
||||
* } else {
|
||||
* return super.getJavaType(clazz);
|
||||
* }
|
||||
* }
|
||||
* </pre>
|
||||
* @param clazz the class to return the java type for
|
||||
* @return the java type
|
||||
*/
|
||||
protected JavaType getJavaType(Class<?> clazz) {
|
||||
return objectMapper.constructType(clazz);
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine the JSON encoding to use for the given content type.
|
||||
* @param contentType the media type as requested by the caller
|
||||
* @return the JSON encoding to use (never <code>null</code>)
|
||||
*/
|
||||
protected JsonEncoding getJsonEncoding(MediaType contentType) {
|
||||
if (contentType != null && contentType.getCharSet() != null) {
|
||||
Charset charset = contentType.getCharSet();
|
||||
for (JsonEncoding encoding : JsonEncoding.values()) {
|
||||
if (charset.name().equals(encoding.getJavaName())) {
|
||||
return encoding;
|
||||
}
|
||||
}
|
||||
}
|
||||
return JsonEncoding.UTF8;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2011 the original author or authors.
|
||||
* 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.
|
||||
@@ -40,6 +40,7 @@ import org.springframework.http.converter.ResourceHttpMessageConverter;
|
||||
import org.springframework.http.converter.StringHttpMessageConverter;
|
||||
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.xml.Jaxb2RootElementHttpMessageConverter;
|
||||
import org.springframework.http.converter.xml.SourceHttpMessageConverter;
|
||||
@@ -118,6 +119,10 @@ public class RestTemplate extends InterceptingHttpAccessor implements RestOperat
|
||||
private static final boolean jaxb2Present =
|
||||
ClassUtils.isPresent("javax.xml.bind.Binder", RestTemplate.class.getClassLoader());
|
||||
|
||||
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());
|
||||
@@ -143,7 +148,10 @@ public class RestTemplate extends InterceptingHttpAccessor implements RestOperat
|
||||
if (jaxb2Present) {
|
||||
this.messageConverters.add(new Jaxb2RootElementHttpMessageConverter());
|
||||
}
|
||||
if (jacksonPresent) {
|
||||
if (jackson2Present) {
|
||||
this.messageConverters.add(new MappingJackson2HttpMessageConverter());
|
||||
}
|
||||
else if (jacksonPresent) {
|
||||
this.messageConverters.add(new MappingJacksonHttpMessageConverter());
|
||||
}
|
||||
if (romePresent) {
|
||||
@@ -384,7 +392,7 @@ public class RestTemplate extends InterceptingHttpAccessor implements RestOperat
|
||||
return execute(url, method, requestCallback, responseExtractor, uriVariables);
|
||||
}
|
||||
|
||||
public <T> ResponseEntity<T> exchange(URI url, HttpMethod method, HttpEntity<?> requestEntity,
|
||||
public <T> ResponseEntity<T> exchange(URI url, HttpMethod method, HttpEntity<?> requestEntity,
|
||||
Class<T> responseType) throws RestClientException {
|
||||
HttpEntityRequestCallback requestCallback = new HttpEntityRequestCallback(requestEntity, responseType);
|
||||
ResponseEntityResponseExtractor<T> responseExtractor = new ResponseEntityResponseExtractor<T>(responseType);
|
||||
@@ -577,7 +585,7 @@ public class RestTemplate extends InterceptingHttpAccessor implements RestOperat
|
||||
}
|
||||
if (logger.isDebugEnabled()) {
|
||||
if (requestContentType != null) {
|
||||
logger.debug("Writing [" + requestBody + "] as \"" + requestContentType +
|
||||
logger.debug("Writing [" + requestBody + "] as \"" + requestContentType +
|
||||
"\" using [" + messageConverter + "]");
|
||||
}
|
||||
else {
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2010 the original author or authors.
|
||||
* 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.
|
||||
@@ -23,29 +23,47 @@ import static org.junit.Assert.assertTrue;
|
||||
import java.io.IOException;
|
||||
import java.nio.charset.Charset;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collection;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import org.codehaus.jackson.map.type.TypeFactory;
|
||||
import org.codehaus.jackson.type.JavaType;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.junit.runners.Parameterized;
|
||||
import org.junit.runners.Parameterized.Parameters;
|
||||
import org.springframework.http.MediaType;
|
||||
import org.springframework.http.MockHttpInputMessage;
|
||||
import org.springframework.http.MockHttpOutputMessage;
|
||||
import org.springframework.http.converter.HttpMessageConverter;
|
||||
import org.springframework.http.converter.HttpMessageNotReadableException;
|
||||
|
||||
/**
|
||||
* Jackson conversion tests parameterized with Jackson and Jackson 2 converters.
|
||||
*
|
||||
* @author Arjen Poutsma
|
||||
* @author Rossen Stoyanchev
|
||||
*/
|
||||
@RunWith(Parameterized.class)
|
||||
public class MappingJacksonHttpMessageConverterTests {
|
||||
|
||||
private MappingJacksonHttpMessageConverter converter;
|
||||
private HttpMessageConverter<Object> converter;
|
||||
|
||||
@Before
|
||||
public void setUp() {
|
||||
converter = new MappingJacksonHttpMessageConverter();
|
||||
@Parameters
|
||||
public static Collection<Object[]> handlerTypes() {
|
||||
Object[][] array = new Object[2][1];
|
||||
|
||||
array[0] = new Object[] { new MappingJackson2HttpMessageConverter()};
|
||||
array[1] = new Object[] { new MappingJacksonHttpMessageConverter()};
|
||||
|
||||
return Arrays.asList(array);
|
||||
}
|
||||
|
||||
public MappingJacksonHttpMessageConverterTests(HttpMessageConverter<Object> converter) {
|
||||
this.converter = converter;
|
||||
}
|
||||
|
||||
@Test
|
||||
|
||||
@@ -6,6 +6,7 @@ Import-Template:
|
||||
com.caucho.*;version="[3.2.0, 5.0.0)";resolution:=optional,
|
||||
com.sun.syndication.*;version="[1.0.0, 2.0.0)";resolution:=optional,
|
||||
org.codehaus.jackson.*;version="[1.3.0, 2.0.0)";resolution:=optional,
|
||||
com.fasterxml.jackson.*;version="[2.0.0, 3.0.0)";resolution:=optional,
|
||||
com.sun.net.*;version="0";resolution:=optional,
|
||||
javax.activation.*;version="0";resolution:=optional,
|
||||
javax.el.*;version="[1.0.0, 3.0.0)";resolution:=optional,
|
||||
|
||||
@@ -152,6 +152,40 @@
|
||||
</SOURCES>
|
||||
</library>
|
||||
</orderEntry>
|
||||
<orderEntry type="module-library">
|
||||
<library>
|
||||
<CLASSES>
|
||||
<root url="jar://$IVY_CACHE$/com.fasterxml.jackson.core/com.springsource.com.fasterxml.jackson.core.jackson-databind/2.0.2/com.springsource.com.fasterxml.jackson.core.jackson-databind-2.0.2.jar!/" />
|
||||
</CLASSES>
|
||||
<JAVADOC />
|
||||
<SOURCES>
|
||||
<root url="jar://$IVY_CACHE$/com.fasterxml.jackson.core/com.springsource.com.fasterxml.jackson.core.jackson-databind/2.0.2/com.springsource.com.fasterxml.jackson.core.jackson-databind-2.0.2-sources.jar!/" />
|
||||
</SOURCES>
|
||||
</library>
|
||||
</orderEntry>
|
||||
<orderEntry type="module-library">
|
||||
<library>
|
||||
<CLASSES>
|
||||
<root url="jar://$IVY_CACHE$/com.fasterxml.jackson.core/com.springsource.com.fasterxml.jackson.core.jackson-core/2.0.2/com.springsource.com.fasterxml.jackson.core.jackson-core-2.0.2.jar!/" />
|
||||
</CLASSES>
|
||||
<JAVADOC />
|
||||
<SOURCES>
|
||||
<root url="jar://$IVY_CACHE$/com.fasterxml.jackson.core/com.springsource.com.fasterxml.jackson.core.jackson-core/2.0.2/com.springsource.com.fasterxml.jackson.core.jackson-core-2.0.2-sources.jar!/" />
|
||||
</SOURCES>
|
||||
</library>
|
||||
</orderEntry>
|
||||
<orderEntry type="module-library">
|
||||
<library>
|
||||
<CLASSES>
|
||||
<root url="jar://$IVY_CACHE$/com.fasterxml.jackson.core/com.springsource.com.fasterxml.jackson.core.jackson-annotations/2.0.2/com.springsource.com.fasterxml.jackson.core.jackson-annotations-2.0.2.jar!/" />
|
||||
</CLASSES>
|
||||
<JAVADOC />
|
||||
<SOURCES>
|
||||
<root url="jar://$IVY_CACHE$/com.fasterxml.jackson.core/com.springsource.com.fasterxml.jackson.core.jackson-annotations/2.0.2/com.springsource.com.fasterxml.jackson.core.jackson-annotations-2.0.2-sources.jar!/" />
|
||||
</SOURCES>
|
||||
</library>
|
||||
</orderEntry>
|
||||
|
||||
<orderEntry type="module-library">
|
||||
<library>
|
||||
<CLASSES>
|
||||
|
||||
Reference in New Issue
Block a user