2017-01-27 8 views
11

मैं जैक्सन 1.9.13 (और जैक्सन 2.5.0) के साथ क्रमांकन/deserialization और किसी भी सफलता के बिना कुछ दिनों के लिए अब इस लड़ के साथ एक समस्या है।जैक्सन एंड JSONAnySetter: क्रमबद्धता दौरान NullPointer अपवाद/Deserialization

मेरा लक्ष्य @JsonAnyGetter & @JsonAnySetter का उपयोग करना है, और यदि गति को आउटपुट में लिखा जाना चाहिए या नहीं, तो मैं गतिशील रूप से गणना करना चाहता हूं। मैं एक JSON परिभाषा जो मैं ObjectMapper साथ क्रमानुसार (और देखें कि क्या वस्तु या शामिल किया जाना चाहिए नहीं है), और फिर मैं एक स्ट्रिंग के लिए वापस वस्तु कन्वर्ट।

मैं इस के लिए एक "HidableSerializer" है, जो क्रमबद्धता के दौरान ठीक काम करता है का उपयोग कर रहा है, लेकिन नहीं जब वस्तु वापस एक स्ट्रिंग में कनवर्ट करने।

@JsonAnySetter/-getter या "HidableSerializer" के बिना, हर चीज ठीक काम करती है, लेकिन दोनों एक साथ नहीं।

क्यों इस काम नहीं कर रहा? और मैं समस्या को कैसे हल कर सकता हूं? बेहतर दृष्टिकोण स्वागत है!

स्टैक ट्रेस इस तरह दिखता है:

स्टैक ट्रेस

org.codehaus.jackson.map.JsonMappingException: (was java.lang.NullPointerException) (through reference chain: ch.hasselba.Test["[anySetter]"]) 
null 
    at org.codehaus.jackson.map.JsonMappingException.wrapWithPath(JsonMappingException.java:218) 
    at org.codehaus.jackson.map.JsonMappingException.wrapWithPath(JsonMappingException.java:183) 
    at org.codehaus.jackson.map.ser.std.SerializerBase.wrapAndThrow(SerializerBase.java:140) 
    at org.codehaus.jackson.map.ser.std.BeanSerializerBase.serializeFields(BeanSerializerBase.java:158) 
    at org.codehaus.jackson.map.ser.BeanSerializer.serialize(BeanSerializer.java:112) 
at ch.hasselba.HidableSerializer.serialize(HidableSerializer.java:29) 
    at org.codehaus.jackson.map.ser.StdSerializerProvider._serializeValue(StdSerializerProvider.java:610) 
    at org.codehaus.jackson.map.ser.StdSerializerProvider.serializeValue(StdSerializerProvider.java:256) 
    at org.codehaus.jackson.map.ObjectMapper._configAndWriteValue(ObjectMapper.java:2575) 
    at org.codehaus.jackson.map.ObjectMapper.writeValueAsString(ObjectMapper.java:2097) 
    at ch.hasselba.Demo.main(Demo.java:54) 
Caused by: java.lang.NullPointerException 
    at org.codehaus.jackson.map.ser.std.MapSerializer.serializeFields(MapSerializer.java:243) 
    at org.codehaus.jackson.map.ser.AnyGetterWriter.getAndSerialize(AnyGetterWriter.java:41) 
    at org.codehaus.jackson.map.ser.std.BeanSerializerBase.serializeFields(BeanSerializerBase.java:154) 
    ... 7 more 

डेमो कोड

package ch.hasselba; 

import org.codehaus.jackson.Version; 
import org.codehaus.jackson.map.JsonSerializer; 
import org.codehaus.jackson.map.ObjectMapper; 
import org.codehaus.jackson.map.SerializationConfig; 
import org.codehaus.jackson.map.introspect.BasicBeanDescription; 
import org.codehaus.jackson.map.module.SimpleModule; 
import org.codehaus.jackson.map.ser.BeanSerializerModifier; 

public class Demo { 

    public static void main(String[] args) { 

     ObjectMapper mapper = new ObjectMapper(); 

     // register the module 
     Version version = new Version(1, 0, 0, "SNAPSHOT"); 
     mapper.registerModule(new SimpleModule("HidableModule", version) { 
      @Override 
      public void setupModule(SetupContext context) { 
       super.setupModule(context); 
       context.addBeanSerializerModifier(new BeanSerializerModifier() { 
        @SuppressWarnings("unchecked") 
        @Override 
        public JsonSerializer<?> modifySerializer(SerializationConfig config, BasicBeanDescription desc, 
         JsonSerializer<?> serializer) { 
         if (IHidable.class.isAssignableFrom(desc.getBeanClass())) { 
          return new HidableSerializer<Object>((JsonSerializer<Object>) serializer); 
         } 
         return serializer; 
        } 
       }); 
      } 
     }); 

     // the data 
     String content = "{ \"foo\": \"bar\" }"; 

     // build the Object 
     Test test = null; 
     try { 
      test = mapper.readValue(content, Test.class); 
     } catch (Exception e) { 
      e.printStackTrace(); 
     } 

     // and now convert it back to a String 
     String data = null; 
     try { 
      data = mapper.writeValueAsString(test); 
     } catch (Exception e) { 
      e.printStackTrace(); 
     } 

     System.out.println(data); 

    } 

} 

टेस्ट वर्ग

package ch.hasselba; 

import java.util.Map; 
import java.util.concurrent.ConcurrentHashMap; 

import org.codehaus.jackson.annotate.JsonAnyGetter; 
import org.codehaus.jackson.annotate.JsonAnySetter; 

public class Test implements IHidable { 

    private Map<String, Object> others = new ConcurrentHashMap<String, Object>(); 

    @JsonAnyGetter 
    public Map<String, Object> getOthers() { 
     return this.others; 
    } 

    @JsonAnySetter 
    public void addOther(final String name, final Object value) { 
     this.others.put(name, value); 
    } 

    @Override 
    public boolean isHidden() { 
     return false; 
    } 

} 

छिपाने योग्य Serializer

package ch.hasselba; 

import java.io.IOException; 

import org.codehaus.jackson.JsonGenerator; 
import org.codehaus.jackson.JsonProcessingException; 
import org.codehaus.jackson.map.JsonSerializer; 
import org.codehaus.jackson.map.SerializerProvider; 

public class HidableSerializer<T> extends JsonSerializer<T> { 

    private JsonSerializer<T> defaultSerializer; 

    public HidableSerializer(JsonSerializer<T> serializer) { 
     defaultSerializer = serializer; 
    } 

    @Override 
    public void serialize(T value, JsonGenerator jgen, SerializerProvider provider) 
      throws IOException, JsonProcessingException { 

     if(value instanceof IHidable){ 
      IHidable hidableValue = (IHidable) value; 
      if(hidableValue.isHidden()) 
       return; 
     } 
     defaultSerializer.serialize(value, jgen, provider); 

    } 

} 

IHidableInterface

package ch.hasselba; 


public interface IHidable { 
    boolean isHidden(); 
} 
+0

मैं जैक्सन 2.5.0, एक ही मुद्दे के साथ यह परीक्षण किया है। –

उत्तर

4

समस्या यह है कि defaultSerializer उदाहरण, आप अपने HidableSerializer अंदर उपयोग कर रहे हैं, एक ResolvableSerializer है (बीनसेरियलाइज़र), लेकिन ए एस आप अपने modifySerializer() विधि में JsonSerializer (HidableSerializer) में लपेट, यह संकल्प() विधि तो कभी नहीं शुरू हो जाती है है और यह उचित रूप से प्रारंभ करने में विफल रहता।

आप अपने HidableSerializer.serialize में निम्न पंक्ति जोड़कर प्रयास करते हैं() विधि:

... 
((ResolvableSerializer)defaultSerializer).resolve(provider); 
defaultSerializer.serialize(value, jgen, provider); 
... 

यह चाल करना चाहिए।

यह आपके लिए काम करता है, एक अधिक स्थायी समाधान अपने HidableSerializerdefaultSerializer को ResolvableSerializer खुद को लागू करने और सिर्फ संकल्प (प्रतिनिधि) बनाने के लिए हो सकता है, इस तरह:

@Override 
public void resolve(SerializerProvider serializerProvider) throws JsonMappingException { 
    if(defaultSerializer instanceof ResolvableSerializer) { 
     ((ResolvableSerializer)defaultSerializer).resolve(serializerProvider); 
    } 
} 
3

मैं डीबगिंग प्रक्रिया के माध्यम से गया और कुछ code:

if (ser instanceof ResolvableSerializer) { 
    ((ResolvableSerializer) ser).resolve(provider); 
} 

यह वास्तव में कुंजी धारावाहिक को तुरंत चालू करता है जो आपके मामले में एनपीई फेंकता है।

अपने HidableSerializer संशोधित करें और यह चाल करना होगा:

public class HidableSerializer<T> extends JsonSerializer<T> implements ResolvableSerializer { 

    private JsonSerializer<T> defaultSerializer; 

    public HidableSerializer(JsonSerializer<T> serializer) { 
     defaultSerializer = serializer; 
    } 

    @Override 
    public void serialize(T value, JsonGenerator jgen, SerializerProvider provider) 
     throws IOException, JsonProcessingException { 

     if(value instanceof IHidable){ 
      IHidable hidableValue = (IHidable) value; 
      if(hidableValue.isHidden()) 
       return; 
     } 
     defaultSerializer.serialize(value, jgen, provider); 

    } 

    @Override 
    public void resolve(SerializerProvider provider) throws JsonMappingException { 
     ((ResolvableSerializer)defaultSerializer).resolve(provider); 
    } 
} 
+0

मैं बिल्कुल उसी निष्कर्ष पर आया, बस आधे घंटे पहले (नीचे मेरा जवाब देखें) :) – zeppelin

+0

धन्यवाद, लेकिन जैसा कि @ ज़ेपेल्लिन ने लिखा था, उसका समाधान थोड़ा पहले आया था। –

संबंधित मुद्दे