2015-11-25 27 views
3

我正在使用Jersey 2.22.1和Jackson 2.6.3編寫Web應用程序。我的pom.xml看起來是這樣的:無法讓球衣2應用程序使用自定義傑克遜XmlMapper

<!-- 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, 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<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); 
     } 
    } 
    } 
} 

他們兩人都是其中的應用程序資源類

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

如果我做同樣的登記包GET請求方法,@Produces(MediaType.APPLICATION_JSON)一切都很好,我的自定義映射器被使用。但是,如果我向方法提出同樣的請求,@Produces(MediaType.APPLICATION_XML)應用程序使用一些默認的映射器而不是我自定義的映射器。如果你有任何想法請幫助。 謝謝!

+0

你介意包括一些代碼嗎?最好的解決問題的骨頭。 –

回答

5

所以有幾件事。首先,你需要的不僅僅是核心傑克遜XML的依賴,你需要的實際jaxrs provider

<dependency> 
    <groupId>com.fasterxml.jackson.jaxrs</groupId> 
    <artifactId>jackson-jaxrs-xml-provider</artifactId> 
    <version>${jackson2.version}</version> 
</dependency> 

那麼你應該排除JAXB提供商,這是新澤西州所使用的默認提供商。 (我在測試時沒有問題,但如果你不打算使用它,我只會排除它)。它是由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"); 
} 

然後最後你需要參數化ContextResolverXmlMapper類型,而不是ObjectMapper。如看到here,供應商爲XmlMapper尋找ContextResolver,而不是ObjectMapper