2012-10-29 34 views
5

के साथ जेनेरिक प्रकार का Deserializing मैं POJO के deserialize करने के लिए जैक्सन का उपयोग करने वाली कक्षा बनाने की कोशिश कर रहा हूं।जैक्सन

यह इस तरह दिखता है ...

public class DeserialiserImp<T> implements Deserialiser<T> { 

     protected ObjectMapper objectMapper = new ObjectMapper(); 

     @Override 
     public T get(String content, Class clazz) throws IOException { 
      return (T) objectMapper.readValue(content, clazz); 
     } 

     @Override 
     public List<T> getList(String content, Class clazz) throws IOException { 
      return objectMapper.readValue(content, TypeFactory.collectionType(ArrayList.class, clazz)); 
     } 

    } 

मैं इस कार्यान्वयन के बारे में 2 प्रश्न हैं।

पहला यह है कि मैं वर्ग प्रकार को विधियों में गुजर रहा हूं ताकि ऑब्जेक्टमैपर उस प्रकार को जानता हो जिसे deserialize करना चाहिए। जेनिक्स का उपयोग कर एक बेहतर तरीका है?

इसके अलावा विधि प्राप्त करने में मैं ऑब्जेक्ट मैपर से टी पर लौटाई गई वस्तु कास्टिंग कर रहा हूं। ऐसा करने का विशेष रूप से बुरा तरीका लगता है क्योंकि मुझे यहां टी डालना है और फिर मुझे ऑब्जेक्ट प्रकार को विधि से भी डालना है इसे बुला रहा है

मैं इस परियोजना में रोबोगुइस का उपयोग कर रहा हूं, इसलिए यह अच्छा होगा अगर मैं इंजेक्शन के माध्यम से प्रकार बदल सकता हूं और उस ऑब्जेक्ट को एनोटेट कर सकता हूं जो जेनेरिक प्रकार को वापस करने की आवश्यकता है। मैंने TypeLiteral पढ़ा और यह सोचकर कि क्या यह इस समस्या को हल कर सकता है?

+0

देखें http://stackoverflow.com/questions/17400850/is-jackson-really-unable-to-deserialize-json-into-a-generic-type – lisak

उत्तर

5

तो मुझे लगता है कि मैंने इसे अंत में समझ लिया। यदि आप जो कर रहे हैं उसके साथ कुछ गलत देखते हैं तो कृपया टिप्पणी करें।

इंटरफ़ेस इसलिए की तरह परिभाषित किया गया है ...

public interface Deserialiser<T> { 

    T get(String content) throws IOException; 

    List<T> getList(String content) throws IOException; 
} 

इंटरफ़ेस के कार्यान्वयन इस तरह है ...

public class DeserialiserImp<T> implements Deserialiser<T> { 

    private ObjectMapper objectMapper = new ObjectMapper(); 
    private final Class<T> klass; 

    @Inject 
    public DeserialiserImp(TypeLiteral<T> type){ 
     this.klass = (Class<T>) type.getRawType(); 
    } 

    @Override 
    public T get(String content) throws IOException { 
     return objectMapper.readValue(content, klass); 
    } 

    @Override 
    public List<T> getList(String content) throws IOException { 
     return objectMapper.readValue(content, TypeFactory.collectionType(ArrayList.class, klass)); 
    } 

} 

मैं बहुत की तरह 2 बाँध ..

bind(new TypeLiteral<Deserialiser<User>>(){}).annotatedWith(Names.named("user")).to(new TypeLiteral<DeserialiserImp<User>>(){}); 

तब सभी मैं इसे इस है उपयोग करने के लिए क्या करने की जरूरत ...

@Inject 
@Named("user") 
private Deserialiser<User> deserialiserImp; 

public void test(String userString) { 
    User user = deserialiserImp.get(UserString); 
} 

यह पैटर्न भी अच्छी तरह से करता है, तो एक अमूर्त वर्ग के रूप में कक्षा एक डीएओ वस्तु में उपयोग करने के लिए काम कर सकता था

This लेख मुझे मदद की

5

पहला यह है कि मैं वर्ग प्रकार को विधियों में पास कर रहा हूं ताकि ऑब्जेक्टमैपर उस प्रकार को जानता है जिसे deserialize करना चाहिए। जेनिक्स का उपयोग कर बेहतर तरीका है?

दुर्भाग्यवश नहीं, और यह टाइप एरर के कारण है।

भी मिलता विधि में मैं कास्टिंग कर रहा हूँ एक वस्तु टी objectMapper से लौटे इस कर की विशेष रूप से बुरा तरीके के रूप में मैं मैं यहाँ टी कास्ट करने के लिए है और फिर लगता है के लिए भी ऑब्जेक्ट प्रकार डाली से जिस विधि को कॉल कर रहा है।

इस बजाय कार्य करें:

@Override 
public T get(String content, Class<T> clazz) throws IOException { 
    return objectMapper.readValue(content, clazz); 
} 

मैं इस परियोजना में Roboguice उपयोग कर रहा हूँ तो यह अच्छा होगा अगर मैं इंजेक्शन के माध्यम से प्रकार बदल सकते हैं और फिर वस्तु जो जेनेरिक प्रकार व्याख्या मुझे इसे वापस करने की ज़रूरत है। मैंने TypeLiteral और के बारे में सोचा कि क्या यह इस समस्या को हल कर सकता है?

मैं वास्तव में समझ नहीं पा रहा हूं कि आप क्या हासिल करना चाहते हैं, लेकिन चूंकि आपको कक्षा को किसी भी तरह से पारित करने की आवश्यकता है, क्या यह अभी भी संभव है?

+0

मेरे TypeLiteral आ उपयोग के बारे में बात इस सवाल से http://stackoverflow.com/questions/3370641/how-does-guices-typeliteral-work यह कहता है कि "यहां उपयोग की जाने वाली चाल यह है कि जेनेरिक सुपर प्रकार के हस्ताक्षर उप-वर्गों में संग्रहीत होते हैं और इस प्रकार मिटा दें। " मुझे उम्मीद है कि इस प्रकार में पास न हो। – jiduvah

+1

ठीक है मैं समझता हूँ। मुझे यहां कोई व्यावहारिक समाधान नहीं दिख रहा है, आपको रनटाइम पर इसे पुनर्प्राप्त करने के लिए कहीं भी प्रकार (सादे क्लास ऑब्जेक्ट फ़ील्ड के रूप में फ़ील्ड के रूप में, फ़ील्ड के रूप में ...) को स्टोर करने की आवश्यकता है। मुझे नहीं लगता कि हर बार एक प्रकार की गुजरना एक बड़ी समस्या है, क्योंकि यह सभी unmarshalling पुस्तकालयों द्वारा आवश्यक है। हालांकि मुझे एक अन्य दृष्टिकोण देखने में दिलचस्पी होगी। –

+0

ठीक है, मैं कोड क्लीनर बनाने की कोशिश कर रहा हूं। फिलहाल मैं deserialiserImp को तुरंत चालू करते समय सामान्य में टाइप करता हूं, मुझे कक्षा में विधि में गुजरना पड़ता है, फिर मुझे उस ऑब्जेक्ट को भी डालना होगा जो मुझे प्राप्त होता है। तो मैं 3 बार मैं इस प्रकार का संदर्भ देता हूं। यह बहुत गन्दा लगता है – jiduvah