如何解决无法获取jersey 2应用程序以使用自定义杰克逊XmlMapper
有几件事。首先,您不仅需要核心Jackson xml依赖项,还需要实际的jaxrs提供程序
<dependency>
<groupId>com.fasterxml.jackson.jaxrs</groupId>
<artifactId>jackson-jaxrs-xml-provider</artifactId>
<version>${jackson2.version}</version>
</dependency>
然后,您应该排除JAXB提供程序,这是Jersey所使用的默认提供程序。(我在测试时保留它没有问题,但是如果您不打算使用它,我将排除它)。它是由jersey-
server
插入的,因此您应明确声明jersey-server
并jersey-media-jaxb
从中排除
<dependency>
<groupId>org.glassfish.jersey.core</groupId>
<artifactId>jersey-server</artifactId>
<version>${jersey2.version}</version>
<exclusions>
<exclusion>
<groupId>org.glassfish.jersey.media</groupId>
<artifactId>jersey-media-jaxb</artifactId>
</exclusion>
</exclusions>
</dependency>
然后,您将需要注册JacksonJaxbXMLProvider
(或JacksonXMLProvider
不需要或计划使用JAXB批注的)。
public CCRestResources() {
register(JacksonFeature.class);
register(JacksonJaxbXMLProvider.class);
packages("com.cc.rest.jersey");
}
最后,您需要将参数ContextResolver
化为XmlMapper
类型,而不是ObjectMapper
。可以看出这里的供应商寻找一ContextResolver
对XmlMapper
,没有ObjectMapper
。
解决方法
我正在使用Jersey 2.22.1和Jackson 2.6.3编写Web应用程序。我的pom.xml看起来像这样:
<!-- JERSEY -->
<dependency>
<groupId>org.glassfish.jersey.containers</groupId>
<artifactId>jersey-container-servlet</artifactId>
<version>2.22.1</version>
</dependency>
<dependency>
<groupId>org.glassfish.jersey.core</groupId>
<artifactId>jersey-client</artifactId>
<version>2.22.1</version>
</dependency>
<dependency>
<groupId>org.glassfish.jersey.media</groupId>
<artifactId>jersey-media-json-jackson</artifactId>
<version>2.22.1</version>
</dependency>
<dependency>
<groupId>org.glassfish.jersey.media</groupId>
<artifactId>jersey-media-multipart</artifactId>
<version>2.22.1</version>
</dependency>
<dependency>
<groupId>asm</groupId>
<artifactId>asm</artifactId>
<version>3.3.1</version>
</dependency>
<dependency>
<groupId>org.codehaus.woodstox</groupId>
<artifactId>woodstox-core-asl</artifactId>
<version>4.4.1</version>
</dependency>
<!-- JACKSON -->
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-core</artifactId>
<version>2.6.3</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>2.6.3</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-annotations</artifactId>
<version>2.6.3</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.dataformat</groupId>
<artifactId>jackson-dataformat-xml</artifactId>
<version>2.6.3</version>
</dependency>
目标是将不同的自定义ObjectMappers用于JSON和XML映射。我创建了两个提供程序类:JSONMapperProvider
@Provider
@Produces(MediaType.APPLICATION_JSON)
public class JSONMapperProvider implements ContextResolver<ObjectMapper> {
private static ObjectMapper objectMapper;
public JSONMapperProvider() {
init();
}
public static void init() {
if (objectMapper == null) {
objectMapper = new ObjectMapper();
// SERIALIZATION
objectMapper.configure(SerializationFeature.INDENT_OUTPUT,true)
.configure(SerializationFeature.FAIL_ON_EMPTY_BEANS,false)
.configure(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS,false)
.configure(SerializationFeature.WRITE_DATE_KEYS_AS_TIMESTAMPS,false)
.setSerializationInclusion(Include.NON_NULL)
.setSerializationInclusion(Include.NON_EMPTY);
// DESERIALIZATION
objectMapper.configure(DeserializationFeature.USE_BIG_DECIMAL_FOR_FLOATS,true)
.configure(DeserializationFeature.ACCEPT_EMPTY_STRING_AS_NULL_OBJECT,true);
// set up ISO 8601 date/time stamp format:
ObjectMapperProvider.DATE_FORMAT_ISO8601.setTimeZone(TimeZone.getTimeZone("GMT"));
objectMapper.setDateFormat(ObjectMapperProvider.DATE_FORMAT_ISO8601);
// Custom deserializer for date which helps deserialization of date
// without time
SimpleModule dateDeserializerModule = new SimpleModule("DateDeserializerModule",Version.unknownVersion());
dateDeserializerModule.addDeserializer(Date.class,new CustomJsonDateDeserializer());
//objectMapper.registerModule(dateDeserializerModule);
}
}
@Override
public ObjectMapper getContext(Class<?> type) {
System.out.println("JSONMapperProvider.getContext() called with type: "
+ type);
return objectMapper;
}
private static class CustomJsonDateDeserializer extends JsonDeserializer<Date> {
@Override
public Date deserialize(JsonParser jsonparser,DeserializationContext deserializationcontext) throws IOException,JsonProcessingException {
String date = jsonparser.getText();
try {
return DateUtil.parseDate(date);
} catch (ParseException e) {
throw new RuntimeException(e);
}
}
}
}
和XMLMapperProvider
@Provider
@Produces({ MediaType.APPLICATION_XML })
public class XMLMapperProvider implements ContextResolver<ObjectMapper> {
private static ObjectMapper objectMapper;
public XMLMapperProvider() {
init();
}
public static void init() {
if (objectMapper == null) {
JacksonXmlModule module = new JacksonXmlModule();
module.setDefaultUseWrapper(false);
objectMapper = new XmlMapper(module);
// SERIALIZATION
objectMapper.configure(SerializationFeature.INDENT_OUTPUT,new CustomJsonDateDeserializer());
objectMapper.registerModule(dateDeserializerModule);
}
}
@Override
public ObjectMapper getContext(Class<?> type) {
System.out.println("XMLMapperProvider.getContext() called with type: "
+ type);
return objectMapper;
}
private static class CustomJsonDateDeserializer extends JsonDeserializer<Date> {
@Override
public Date deserialize(JsonParser jsonparser,JsonProcessingException {
String date = jsonparser.getText();
try {
return DateUtil.parseDate(date);
} catch (ParseException e) {
throw new RuntimeException(e);
}
}
}
}
它们都在同一包中,并在Application资源类中注册
@ApplicationPath("resources")
public class CCRestResources extends ResourceConfig {
public CCRestResources() {
register(JacksonFeature.class);
packages("com.cc.rest.jersey");
}
}
如果我向@Produces(MediaType.APPLICATION_JSON)的方法发出GET请求,则一切正常,并使用了我的自定义映射器。但是,如果我提出相同的要求,请@Produces(MediaType.APPLICATION_XML)应用程序使用某些默认映射器,而不是我的自定义映射器。如果您有任何想法请帮助。谢谢!
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。