无法获得jersey 2应用程序使用自定义jackson XmlMapper

我正在使用Jersey 2.22.1和Jackson 2.6.3编写Web应用程序。 我的pom.xml看起来像这样:

  org.glassfish.jersey.containers jersey-container-servlet 2.22.1   org.glassfish.jersey.core jersey-client 2.22.1   org.glassfish.jersey.media jersey-media-json-jackson 2.22.1   org.glassfish.jersey.media jersey-media-multipart 2.22.1   asm asm 3.3.1   org.codehaus.woodstox woodstox-core-asl 4.4.1    com.fasterxml.jackson.core jackson-core 2.6.3   com.fasterxml.jackson.core jackson-databind 2.6.3   com.fasterxml.jackson.core jackson-annotations 2.6.3   com.fasterxml.jackson.dataformat jackson-dataformat-xml 2.6.3  

目标是使用不同的自定义ObjectMapper进行JSON和XML映射。 我创建了两个提供程序类:JSONMapperProvider

  @Provider @Produces(MediaType.APPLICATION_JSON) public class JSONMapperProvider implements ContextResolver { 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 { @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 { 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, 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("XMLMapperProvider.getContext() called with type: " + type); return objectMapper; } private static class CustomJsonDateDeserializer extends JsonDeserializer { @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); } } } } 

它们都在Application资源类中注册的同一个包中

 @ApplicationPath("resources") public class CCRestResources extends ResourceConfig { public CCRestResources() { register(JacksonFeature.class); packages("com.cc.rest.jersey"); } } 

如果我向@Produces(MediaType.APPLICATION_JSON)的方法发出GET请求,一切都很好,并且使用了我的自定义映射器。 但是,如果我向emthod提出相同的请求@Produces(MediaType.APPLICATION_XML)应用程序使用一些默认映射器而不是我的自定义映射器。 如果您有任何想法,请帮忙。 谢谢!

所以有一些事情。 首先,您需要的不仅仅是核心Jackson xml依赖项,您需要实际的jaxrs提供程序

  com.fasterxml.jackson.jaxrs jackson-jaxrs-xml-provider ${jackson2.version}  

然后你应该排除JAXB提供程序,它是Jersey使用的默认提供程序。 (测试时我没有遇到任何问题,但是如果你不打算使用它,我会把它排除在外)。 它被jersey-server jersey-media-jaxb ,所以你应该明确声明jersey-serverjersey-media-jaxb排除jersey-media-jaxb

  org.glassfish.jersey.core jersey-server ${jersey2.version}   org.glassfish.jersey.media jersey-media-jaxb    

然后,您需要注册JacksonJaxbXMLProvider (如果您不需要或计划使用JAXB注释,则只需注册JacksonJaxbXMLProvider )。

 public CCRestResources() { register(JacksonFeature.class); register(JacksonJaxbXMLProvider.class); packages("com.cc.rest.jersey"); } 

最后,您需要将ContextResolver参数化为XmlMapper类型,而不是ObjectMapper 。 如此处所示,提供程序为XmlMapper查找XmlMapper ,而不是ObjectMapper