2015-01-23 10 views
5

जैक्सन के पिछले संस्करण में (1.9.2) निम्नलिखित कोड ठीक काम किया:बाकी जैक्सन JsonDeserialize, StackOverflowError के बाद उन्नयन

import org.codehaus.jackson.map.JsonDeserializer; 
import org.codehaus.jackson.JsonParser; 
import org.codehaus.jackson.map.DeserializationContext; 
... 
@JsonDeserialize(using = RoleDeserializer.class) 
public interface RoleDto {} 

public class RoleDeserializer extends SomeSharedDeserializer<RoleDto> {} 

public class SomeSharedDeserializer<T> extends JsonDeserializer<T> { 
    @Override 
    public T deserialize(JsonParser jp, DeserializationContext ctxt) throws IOException 
    { 
     return jp.readValueAs(getImplementation()); 
    } 

    public Class<? extends T> getImplementation(){ ... returns some generated implementation of RoleDto } 
} 

हम पिछले जैक्सन संस्करण (1.9.13 Wildfly 8.2 द्वारा प्रदान के लिए चले जाने के बाद

com.fasterxml.jackson.databind.JsonMappingException: RoleDto, समस्या की उदाहरण का निर्माण नहीं कर सकता:) तो एक अपवाद मिल गया सार प्रकार या तो ठोस प्रकार के मैप किया जा करने की जरूरत है, कस्टम deserializer है, या हो सकता हैके साथ तत्कालअतिरिक्त प्रकार की जानकारी जैक्सन नए संकुल में के रूप में

ठीक है, उपयोग किया जाता है, हम उन्हें करने के लिए उन्नत:

import com.fasterxml.jackson.databind.DeserializationContext; 
import com.fasterxml.jackson.databind.JsonDeserializer; 
import com.fasterxml.jackson.databind.deser.std.JsonNodeDeserializer; 

deserializer दिख रहा है अब (पिछले अपवाद चला गया है), हालांकि, हम मिल StackOverflow त्रुटि अपवाद। com.fasterxml.jackson.databind.ObjectMapper पढ़ता मूल्य (लाइन 3023):

DeserializationContext ctxt = createDeserializationContext(jp, cfg); 
    JsonDeserializer<Object> deser = _findRootDeserializer(ctxt, valueType); 
    // ok, let's get the value 
    if (cfg.useRootWrapping()) { 
     result = _unwrapAndDeserialize(jp, ctxt, cfg, valueType, deser); 
    } else { 
     result = deser.deserialize(jp, ctxt); 
    } 

हम लाइन पर जाएँ: result = deser.deserialize(jp, ctxt);

यह अनंत लूप और StackOverflowError एक परिणाम के रूप का कारण बनता है।

जिस तरह की सिफारिश की है में से एक के रूप में हमारे अपने SomeSharedDeserializer लागू करने के लिए है:

ObjectCodec oc = jp.getCodec(); 
JsonNode node = oc.readTree(jp); 
//here manually create new object and return it 

लेकिन हमारे कक्षाओं उत्पन्न कर रहे हैं। एक अन्य समाधान के रूप में मैंने

ObjectMapper mapper = new ObjectMapper(); 
mapper.readValue(jp, getImplementation()); 

का उपयोग करने का प्रयास किया लेकिन उसी परिणाम - StackOverflow अपवाद।

हम इसे कैसे ठीक कर सकते हैं? क्या हम कुछ deserializer का उपयोग कर सकते हैं, इसे JsonParser इंस्टेंस, जेनरेट क्लास को पास करने के लिए जो बेस इंटरफ़ेस लागू करता है और StackOverflowError के बिना?

उत्तर

1

Here क्या आप समाधान खोजने के लिए एक पूर्ण विवरण और परीक्षण ढूंढ सकते हैं। निम्नलिखित समाधान मिला है:

import com.fasterxml.jackson.core.JsonParser; 
import com.fasterxml.jackson.databind.BeanDescription; 
import com.fasterxml.jackson.databind.DeserializationConfig; 
import com.fasterxml.jackson.databind.DeserializationContext; 
import com.fasterxml.jackson.databind.JsonDeserializer; 
import com.fasterxml.jackson.databind.ObjectMapper; 
import com.fasterxml.jackson.databind.annotation.JsonDeserialize; 
import com.fasterxml.jackson.databind.cfg.DeserializerFactoryConfig; 
import com.fasterxml.jackson.databind.deser.BeanDeserializerFactory; 
import com.fasterxml.jackson.databind.deser.ResolvableDeserializer; 
import com.fasterxml.jackson.databind.type.SimpleType; 
... 
    public abstract class RestDtoDeserializer<T> extends JsonDeserializer<T> 
    { 
     @Override 
     public T deserialize(JsonParser jp, DeserializationContext ctxt) throws IOException 
     { 
      DeserializationConfig config = ctxt.getConfig(); 
      SimpleType simpleType = SimpleType.construct(getImplementationClass()); 
      BeanDescription beanDesc = config.introspect(simpleType); 
      BeanDeserializerFactory instance = new BeanDeserializerFactory(new DeserializerFactoryConfig()); 
      JsonDeserializer deserializer = instance.buildBeanDeserializer(ctxt, simpleType, beanDesc); 
      ((ResolvableDeserializer)deserializer).resolve(ctxt); 
      return (T) deserializer.deserialize(jp, ctxt); 
     } 

     public abstract Class<? extends T> getImplementationClass(); 
संबंधित मुद्दे