2016-07-17 12 views
5

के साथ जैक्सन Deserialization त्रुटि में वास्तव में यह सुनिश्चित नहीं है कि समस्या को कैसे समझाना सबसे अच्छा है, इसलिए मैंने बेहतर प्रदर्शन के लिए जावा और कोटलिन दोनों के समान कोड को मार दिया।कोटलिन में, डेटा क्लास

जब मैं जेएसओएन पढ़ता हूं, ऐसा प्रतीत होता है कि यह डेटा बीन्स मान को न्यूल होने के लिए मजबूर कर रहा है, भले ही पैरामीटर जेसन के साथ शुरू करने के लिए भी नहीं है और डेटा बीन गुम फ़ील्ड के मान को डिफ़ॉल्ट करता है। जावा में यह उस मूल्य को निरस्त करने का प्रयास नहीं करता है जो कभी शुरू करने के लिए प्रदान नहीं किया गया था। कोटलिन में ऐसा लगता है क्योंकि यह एक गैर-शून्य क्षेत्र को खत्म करने की कोशिश करता है।

Kotlin में

data class Pojo(val name: String, val age: Int, val list: List<String> = emptyList(), val ts: Date = Date()) 

private val mapper: ObjectMapper = ObjectMapper().registerModule(KotlinModule()) 
    .disable(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES) 

fun main(args: Array<String>) { 
    mapper.readValue("""{"name": "John Doe", "list": ["yellow", "green"], "age": 42}""", Pojo::class.java) 
} 

कौन सा

java.lang.IllegalArgumentException: Parameter specified as non-null is null: method Pojo.<init>, parameter ts 

की एक अपवाद फेंकता जावा में (सब कुछ ठीक काम करता है)

public class Transform { 
    private static ObjectMapper mapper = new ObjectMapper() 
     .disable(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES); 

    public static class Pojo { 
    private String name; 
    private int age; 
    private List<String> list; 
    private Date ts = new Date(); 
    <getters and setters for all> 
    } 

    public static void main(String[] args) throws IOException { 
    String json = "{\"name\": \"John Doe\", \"list\": [\"yellow\", \"green\"], \"age\": 42}"; 
    Pojo p = mapper.readValue(json, Pojo.class); 
    System.out.printf("Bean: name=%s, age=%s, list=%s, ts=%s\n", p.name, p.age, p.list, p.ts); 
    } 
} 

यहां तक ​​कि अगर मैं इसे एक वर्ग एक डेटा के बजाय बनाने कोटलिन में कक्षा, यह अभी भी वैसे ही त्रुटियों से बाहर है।

मेरा सवाल है, मैं अपने POJO के साथ कोटलिन में काम करने के लिए जैक्सन deserialization कैसे प्राप्त कर सकते हैं। अपेक्षित व्यवहार यह है कि अगर किसी शून्य/गलत मान को शून्य की अनुमति नहीं दी जाती है, तो उसे "तोड़ना" चाहिए। लेकिन ऊपर के परिदृश्य में जहां टी फ़ील्ड को शून्य में बदलने के लिए कोई प्रयास नहीं किया गया था, तो इसे जावा के साथ डिफ़ॉल्ट मान का उपयोग करना चाहिए था।

काम करने के लिए सभी पर डेटा सेम की अवधारणा का उपयोग नहीं करने के लिए और इस तरह

class Pojo(val name: String, val age: Int) { 
    var list: List<String> = emptyList() 
    var ts: Date = Date() 
} 

लेकिन तब मेरी .equals काम नहीं करता है और यह मेरे सेम लिखना है लगता है कि केवल बात यह है कि मेरे मन को पार दूसरों को सूची और टीएस गुणों की सामग्री में हेरफेर करने की इजाजत देता है जब मैं उन्हें केवल पढ़ने के लिए चाहता हूं।

उत्तर

10

यह jackson-kotlin-module की 2.8.0 रिलीज के साथ:

अब निर्माता और निर्माता के तरीकों में मूलभूत मूल्यों का उपयोग कर

निम्न उदाहरण सुविधा को दर्शाया गया है का समर्थन करता है:

data class Question(val title: String = "Is programming hard?", val answer: String) 

val q = mapper.readValue<Question>("""{"answer": "Sure it can be"}""") 
println(q) //-> Question(title=Is programming hard?, answer=Sure it can be) 
+2

सही, यह परिवर्तन 2.8.x के लिए नया था और * पिछले संस्करणों में वापस पोर्ट नहीं किया जा सकता था, इसलिए आपको प्लगइन मॉड्यूल पर अधिक नियंत्रण देने के लिए जैक्सन में नए एपीआई जोड़े गए थे क्योंकि आपको अपग्रेड करना होगा। –

+0

धन्यवाद, यह चाल है। मैं 2.7 का उपयोग कर रहा था।5 जिस समय मैंने इस छोटे से प्रयास को शुरू किया था, वह नवीनतम था। कभी मेरे दिमाग को पार नहीं किया कि मुझे बस libs को अपग्रेड करने की आवश्यकता है। एक आसान फिक्स के लिए खुशी हुई। – Ryba

-1

मुझे लगता है कि आपकी आने वाली संपत्तियों में से एक शून्य है, इसलिए आपको ? को जेसनप्रोपर्टी के बाद रखने की आवश्यकता होगी जो कि शून्य हो सकती है (यदि आपके मामले में यह आपका दिनांक फ़ील्ड है)। आप ट्रिपल कोट्स """\unescaped string""" के साथ अपने परीक्षण के लिए कच्चे स्ट्रिंग डेटा प्रकार का भी उपयोग कर सकते हैं, इसलिए यह आपके डेटा क्लास के अंदर val ts: Date? जैसा होना चाहिए। और आपको इस प्रकार को फिर से शुरू करने की ज़रूरत नहीं है। तो अंतिम जवाब होगा: data class Pojo(val name: String, val age: Int, val list: List<String>, val ts: Date?)

+1

उसने पूछा एक मामला जहां उसके पास पैरामीटर के लिए डिफ़ॉल्ट मान है, जो जैक्सन 2.8.0 आगे (जैसा कि मिनेसोल उल्लेख) के रूप में ठीक काम करता है। और उस रिलीज के लिए शून्यता भी बेहतर है। यदि वह 2.8.0 का उपयोग करता है तो उसे कोई समस्या नहीं होगी। –

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