2014-01-08 3 views
1

Новый Jackson-API предоставляет нам удобное связывание с XML (например, JAXB), но я не могу найти способ сделать сериализацию Jackson типичной «xsi: nil "-Attribute, который является стандартом defacto для представления значений NULL в XML? Пожалуйста, поправьте меня, если я вижу это неправильно ;-)Jackson: привязка к XML - обработка нулевой или пустой строки

В JAXB это можно легко сделать с помощью аннотирования Java-переменного с: @XMLElement (nillable = ИСТИНА)

Смотри также: http://blog.bdoughan.com/2012/04/binding-to-json-xml-handling-null.html

Может ли Джексон это сделать?

для Джексона-XML смотрите: https://github.com/FasterXML/jackson-dataformat-xml

+0

см: https://github.com/FasterXML/jackson-dataformat-xml/issues/89 – rnd

ответ

1

Это не дает ответа на вопрос, но обеспечивает обходной путь (очень Hacky)!

мне удалось написать несколько пользовательских сериализаторы/deserializers для Джексона (до джексон официально не поддерживает XSI: ноль), что позволит:

  • сериализовать значения из POJO как XSI: ноль элементов к XML- Строка, если они являются NULL в POJO
  • десериализации список закодированных типов (String, Integer, Float ...) как NULL на POJO, если они определяются как XSI: ноль элементов в данном XML-струнной

С помощью этого кода можно обеспечить совместимость с ot ее библиотеки привязки xml (JAXB ..), которые могут работать только с xsi: nil для нулевых значений.

Класс товара:

public class Item {   
     public String x; 
     public Integer y;   
     public Integer z; 
    } 

Класс Main:

public class Main { 

     public static void main(String[] args) throws JsonParseException, JsonMappingException, IOException { 
     NumberDeserializers numberDeserializers = new NumberDeserializers(); 

     XmlMapper xmlMapper = new XmlMapper();  
     xmlMapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false); 

     // create custom-serialization 
     XmlSerializerProvider provider = new XmlSerializerProvider(new XmlRootNameLookup()); 
     provider.setNullValueSerializer(new MyNullSerializer()); 
     xmlMapper.setSerializerProvider(provider); 

     // create custom deserialization 
     SimpleModule myModule = new SimpleModule("Module", new Version(1, 9, 10, "FINAL"));  
     myModule.addDeserializer(String.class, new NullableDeserializer(new StringDeserializer()));    
     myModule.addDeserializer(Number.class, new NullableDeserializer(numberDeserializers.find(Integer.class, Integer.class.getName()))); 
     myModule.addDeserializer(Float.class, new NullableDeserializer(numberDeserializers.find(Float.class, Float.class.getName()))); 

     xmlMapper.registerModule(myModule); 

     // deserialize 
     Item value = xmlMapper.readValue(
      "<item xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" ><a></a><x xsi:nil=\"true\"></x><y/><z>13</z></item>", 
      Item.class); 

     // serialize 
     String xml = xmlMapper.writeValueAsString(value); 
     System.out.println(xml); 
     } 
    } 

Класс MyNullSerializer:

public class MyNullSerializer extends JsonSerializer<Object> { 
     @Override 
     public void serialize(Object value, JsonGenerator jgen, SerializerProvider provider) throws IOException, JsonProcessingException { 
     ToXmlGenerator xGen = (ToXmlGenerator) jgen; 

     xGen.writeStartObject(); 
     try { 
      xGen.getStaxWriter().writeAttribute("xsi:nil", "true"); 
     } catch (Exception e){ 
      e.printStackTrace(); 
     } 
     xGen.writeEndObject();  
     } 
    } 

Класс MyNullDeserializer:

public class MyNullDeserializer extends JsonDeserializer { 

     private JsonDeserializer delegate; 

     public MyNullDeserializer(JsonDeserializer delegate){ 
     this.delegate = delegate; 
     } 

     @Override 
     public Object deserialize(JsonParser jp, DeserializationContext ctxt) 
      throws IOException, JsonProcessingException { 

     FromXmlParser fxp = (FromXmlParser) jp; 

     boolean isNil = false; 

     XMLStreamReader reader = fxp.getStaxReader(); 
     if (reader.isStartElement()){ 
      if (reader.getAttributeCount() > 0){ 
      String atVal = reader.getAttributeValue("http://www.w3.org/2001/XMLSchema-instance", "nil"); 
      if (atVal != null){ 
       if (Boolean.parseBoolean(atVal) == true){ 
       isNil = true; 
       } 
      } 
      } 
     } 

     Object value = null; 
     if (isNil == false){ 
      value = delegate.deserialize(jp, ctxt); 
     } else { 
      jp.getValueAsString(); // move forward 
     } 
     return value; 
     } 

    } 
+0

Просьба включить объяснение того, что делает ваш код и как он отвечает на вопрос. Если вы получите фрагмент кода в качестве ответа, вы можете не знать, что с ним делать. Ответ должен дать руководство OP о том, как отлаживать и исправлять свою проблему. Указывая, что представляет собой идея вашего кода, очень помогает в понимании проблемы и применении или изменении вашего решения. – Palec

 Смежные вопросы

  • Нет связанных вопросов^_^