JsonMappingException: टाइप [सरल प्रकार, वर्ग] के लिए कोई उपयुक्त कंस्ट्रक्टर नहीं मिला: JSON ऑब्जेक्ट से तुरंत नहीं हो सकता


438

JSON अनुरोध प्राप्त करने और इसे संसाधित करने का प्रयास करते समय मुझे निम्न त्रुटि मिल रही है:

org.codehaus.jackson.map.JsonMappingException: [उपयुक्त प्रकार, वर्ग com.myweb.ApplesDO] टाइप करने के लिए कोई उपयुक्त कंस्ट्रक्टर नहीं मिला: JSON ऑब्जेक्ट से तत्काल टाइप नहीं कर सकता (टाइप जानकारी को जोड़ने / सक्षम करने की आवश्यकता है?)

यहाँ JSON मैं भेजने की कोशिश कर रहा हूँ:

{
  "applesDO" : [
    {
      "apple" : "Green Apple"
    },
    {
      "apple" : "Red Apple"
    }
  ]
}

नियंत्रक में, मेरे पास निम्नलिखित विधि हस्ताक्षर हैं:

@RequestMapping("showApples.do")
public String getApples(@RequestBody final AllApplesDO applesRequest){
    // Method Code
}

AllApplesDO ApplesDO का एक आवरण है:

public class AllApplesDO {

    private List<ApplesDO> applesDO;

    public List<ApplesDO> getApplesDO() {
        return applesDO;
    }

    public void setApplesDO(List<ApplesDO> applesDO) {
        this.applesDO = applesDO;
    }
}

ApplesDO:

public class ApplesDO {

    private String apple;

    public String getApple() {
        return apple;
    }

    public void setApple(String appl) {
        this.apple = apple;
    }

    public ApplesDO(CustomType custom){
        //constructor Code
    }
}

मुझे लगता है कि जैक्सन उपक्लास के लिए JSON को जावा ऑब्जेक्ट में बदलने में असमर्थ है। जैक्सन को जावा ऑब्जेक्ट में बदलने के लिए जैक्सन के लिए कॉन्फ़िगरेशन मापदंडों की मदद करें। मैं स्प्रिंग फ्रेमवर्क का उपयोग कर रहा हूं।

EDIT: उपरोक्त नमूना वर्ग में यह समस्या पैदा करने वाले प्रमुख बग को शामिल करें - कृपया समाधान के लिए स्वीकृत उत्तर देखें।


2
मुझे उपरोक्त कोड में कोई उपवर्ग नहीं दिख रहा है, क्या यह कोड आपकी कोशिश है या आप एक सरल उदाहरण बना रहे हैं?
गोलमाल

मैंने कुछ और स्पष्टीकरण के साथ एक उत्तर जोड़ा कि यह कैसे काम करता है। मूल रूप से, आपको यह महसूस करने की आवश्यकता है कि जावा रनटाइम में विधि तर्क नाम नहीं रखता है।
वलसेक

जवाबों:


565

तो, आखिरकार मुझे एहसास हुआ कि समस्या क्या है। यह जैक्सन विन्यास मुद्दा नहीं है क्योंकि मुझे संदेह था।

वास्तव में समस्या ApplesDO कक्षा में थी:

public class ApplesDO {

    private String apple;

    public String getApple() {
        return apple;
    }

    public void setApple(String apple) {
        this.apple = apple;
    }

    public ApplesDO(CustomType custom) {
        //constructor Code
    }
}

एक कस्टम कंस्ट्रक्टर था जिसे क्लास के लिए डिफॉल्ट कंस्ट्रक्टर बनाया गया था। एक डमी कंस्ट्रक्टर का परिचय देने से त्रुटि दूर हो गई है:

public class ApplesDO {

    private String apple;

    public String getApple() {
        return apple;
    }

    public void setApple(String apple) {
        this.apple = apple;
    }

    public ApplesDO(CustomType custom) {
        //constructor Code
    }

    //Introducing the dummy constructor
    public ApplesDO() {
    }

}

मैं पूछ सकता हूँ कि CustomType कहाँ से आता है। मैं इस तरह की एक संरचना की कोशिश कर रहा हूं, लेकिन मैं जावा के लिए बिल्कुल नया हूं।
औरो

181
आप आंतरिक (नेस्टेड) ​​वर्गों के साथ जैकसन का उपयोग कर सकते हैं, इस मामले में क्रमांकन ठीक काम करता है। एकमात्र अड़चन ब्लॉक यह है कि आंतरिक वर्ग को ठीक से काम करने के लिए deserialization के लिए "स्थिर" के रूप में चिह्नित किया जाना चाहिए। यहाँ देखें एक्सक्लरेशन: काउटाउनकोडर.com/ blog
archives

3
क्या कोई समझा सकता है कि ऐसा क्यों होता है? मेरे पास एक समान त्रुटि थी। सोचा सभी सही कंस्ट्रक्टर जगह में थे, लेकिन डिसेरिएलाइज नहीं कर सकते थे। इस पोस्ट को पढ़ने के बाद मैंने केवल एक डमी कंस्ट्रक्टर को जोड़ने के बाद ही काम किया।
user8658912

6
@ सुमन मैं इसे डमी कंस्ट्रक्टर नहीं कहूंगा - यह सिर्फ डिफॉल्ट कंस्ट्रक्टर है। न केवल यह पूरी तरह से वैध है, बल्कि कई प्रकार के जावा बीन-प्रकार के प्रसंस्करण के लिए आवश्यक है। (और, ज़ाहिर है, इसने मुझे
उलझा

2
यदि आप डिफ़ॉल्ट कंस्ट्रक्टर नहीं जोड़ना चाहते हैं (उदाहरण के लिए, जब आप अपरिवर्तनीय वस्तुओं के साथ काम कर रहे हैं)। आपको यह बताना होगा कि JsonCreator एनोटेशन का उपयोग करके ऑब्जेक्ट को तुरंत बनाने के लिए किस निर्माता या कारखाने का उपयोग करना है।
राहुल

375

इन कारणों से ऐसा होता है:

  1. आपके आंतरिक वर्ग को स्थैतिक के रूप में परिभाषित किया जाना चाहिए

    private static class Condition {  //jackson specific    
    }
  2. यह हो सकता है कि आपको अपनी कक्षा में कोई डिफ़ॉल्ट निर्माता नहीं मिला ( अद्यतन करें: ऐसा नहीं लगता है)

    private static class Condition {
        private Long id;
    
        public Condition() {
        }
    
        // Setters and Getters
    }
  3. यह हो सकता है कि आपके सेटर ठीक से परिभाषित न हों या दिखाई न दें (जैसे निजी सेटर)


95
स्टेटिक क्लास ने मेरे मामले में फर्क किया। धन्यवाद!
जलोगर

3
और हां, आपको खाली, बिना तर्क के डिफॉल्ट कंस्ट्रक्टर घोषित करने की जरूरत नहीं है, जावा आपके लिए करता है ! (जब तक आप किसी अन्य कंस्ट्रक्टर को परिभाषित नहीं करते हैं।)
जोनिक

1
@ जानिक, सही है! मेरा उत्तर पुराना है, अगर मुझे सही याद है, क्योंकि जैक्सन आंतरिक कक्षा में जाने के लिए प्रतिबिंब का उपयोग कर रहा है, तो मुझे लगता है कि इसे डिफ़ॉल्ट कंस्ट्रक्टर को परिभाषित करने की आवश्यकता थी (नए संस्करणों में भी मामला नहीं हो सकता), लेकिन जब से मैं नहीं हूं सुनिश्चित करें कि आप सही हो सकते हैं।
azerafati

6
हाँ, मेरा अनुभव जैक्सन 2.4.4 के साथ है: वास्तव में जावा का अंतर्निहित डिफ़ॉल्ट निर्माता पर्याप्त है। आप स्पष्ट रूप से लिखने के लिए कोई आर्ग निर्माता की जरूरत है केवल यदि आपके द्वारा निर्धारित अन्य निर्माताओं है कि ले तर्क (यानी जब जावा कोई आर्ग आपके लिए कोड जनरेट नहीं है)।
जोनिक

2
मेरे साथ, स्थिर वर्ग ने दिन बचाया।
साइमन 12

58

मैं इसमें एक और समाधान जोड़ना चाहूंगा जिसमें डमी कंस्ट्रक्टर की आवश्यकता नहीं है। चूंकि डमी कंस्ट्रक्टर थोड़े गन्दे हैं और बाद में भ्रमित होते हैं। हम एक सुरक्षित कंस्ट्रक्टर प्रदान कर सकते हैं और कंस्ट्रक्टर के तर्क की व्याख्या करके हम जैक्सन को कंस्ट्रक्टर पैरामीटर और फ़ील्ड के बीच मैपिंग निर्धारित करने की अनुमति देते हैं।

तो निम्नलिखित भी काम करेगा। नोट नोट के अंदर स्ट्रिंग क्षेत्र के नाम से मेल खाना चाहिए।

import com.fasterxml.jackson.annotation.JsonProperty;
public class ApplesDO {

        private String apple;

        public String getApple() {
            return apple;
        }

        public void setApple(String apple) {
            this.apple = apple;
        }

        public ApplesDO(CustomType custom){
            //constructor Code
        }

        public ApplesDO(@JsonProperty("apple")String apple) {
        }

}

इस समाधान ने चाल चली। मैं केवल निम्नलिखित का उल्लेख करना चाहता हूं, मेरे पास एक निर्माता था, लेकिन मापदंडों का नाम उदाहरण-मापदंडों से अलग था, इसलिए इसे मैप नहीं किया जा सकता था। एनोटेशन को जोड़ने से यह हल हो गया, लेकिन मापदंडों का नाम बदलने से शायद काम भी हो गया।
फिको

क्या होगा अगर कंस्ट्रक्टर पैरामीटर प्रतिक्रिया में नहीं है? क्या इसे दूसरे तरीके से इंजेक्ट किया जा सकता है?
एडी जौडे

केवल महत्वपूर्ण डेटा है कि यहाँ भेजा जा रहा है स्ट्रिंग सेब कि है है प्रतिक्रिया।
प्रायरसीपी

1
यह मेरे लिए उपयोगी था क्योंकि मैं चाहता था कि मेरी वस्तु अपरिवर्तनीय हो, इसलिए एक डमी निर्माणकर्ता कोई विकल्प नहीं था।
जोनाथन पुलानो

मेरे मामले में इसे @JsonCreatorकंस्ट्रक्टर के साथ जोड़ना होगा @JsonProperty
m1ld

31

जब मैं इस समस्या में भाग गया, तो यह डीओ के रूप में सेवा करने के लिए एक आंतरिक वर्ग का उपयोग करने की कोशिश का एक परिणाम था। आंतरिक वर्ग (चुपचाप) के निर्माण के लिए संलग्न वर्ग का एक उदाहरण आवश्यक था - जो जैक्सन के लिए उपलब्ध नहीं था।

इस मामले में, आंतरिक वर्ग को अपनी .java फ़ाइल में ले जाना समस्या को ठीक करता है।


6
जबकि आंतरिक वर्ग को अपनी .java फ़ाइल में ले जाना, स्थैतिक संशोधक को जोड़ना भी समस्या का समाधान करता है जैसा कि @ बल्ड्रीम के उत्तर में बताया गया है।
21

20

आम तौर पर यह त्रुटि आती है क्योंकि हम डिफ़ॉल्ट कंस्ट्रक्टर नहीं बनाते हैं, लेकिन मेरे मामले में यह समस्या केवल माता-पिता वर्ग के अंदर उपयोग किए गए ऑब्जेक्ट क्लास बनाने के कारण आ रही थी। इससे मेरा पूरा दिन बर्बाद हो गया है।


यह नेस्टेड क्लास बनाने के लिए पर्याप्त है static
स्लॉथ

13

अँगूठा नियम : प्रत्येक वर्ग के लिए एक डिफ़ॉल्ट कंस्ट्रक्टर जोड़ें जिसका उपयोग आप मैपिंग क्लास के रूप में करते थे। आप इसे याद किया और मुद्दा उठता है!
बस डिफॉल्ट कंस्ट्रक्टर जोड़ें और यह काम करना चाहिए।


अच्छा जवाब। धन्यवाद मेरा दिन।
स्टीव

9

क्या आप इस संरचना का परीक्षण कर सकते हैं। अगर मुझे सही याद है तो आप इसे इस तरह से उपयोग कर सकते हैं:

{
    "applesRequest": {
        "applesDO": [
            {
                "apple": "Green Apple"
            },
            {
                "apple": "Red Apple"
            }
        ]
    }
}

दूसरा, कृपया प्रत्येक वर्ग में डिफ़ॉल्ट कंस्ट्रक्टर जोड़ें, इससे भी मदद मिल सकती है।


काम नहीं कर रहा है: निम्न त्रुटि हो रही है: "org.codehaus.jackson.map.exc.UnrecognizedPropertyException: अपरिचित फ़ील्ड & quot; applesRequest & quot; (वर्ग com.smart.d.dao.AllApplesDO)), जो प्रज्वलित के रूप में चिह्नित नहीं है"
लकी मुरारी

पहले यह कम से कम AllApplesDO के लिए त्रुटि के माध्यम से नहीं करता था और केवल संलग्न वर्ग के लिए फेंकता था। अब यह पहली कक्षा के लिए खुद को फेंकता है
लकी मुरारी

एक डिफ़ॉल्ट निर्माता की आवश्यकता है। धन्यवाद!
प्लांकी

क्या इसे CORRECT उत्तर के रूप में नहीं चुना जाना चाहिए?
तेज दांत

7

आपको हमारे मॉडल वर्ग में डमी खाली कंस्ट्रक्टर बनाना होगा। जौन मैपिंग करते समय, यह सेटर विधि द्वारा निर्धारित होता है।


यह तय है।
डेविड कोबिया

मेरे लिए भी यही बात है। मेरी वस्तु के लिए मेरे पास कई अलग-अलग निर्माता थे, और इसलिए मैंने सिर्फ एक और खाली बनाया जो जाहिरा तौर पर जैकसन द्वारा उपयोग किया जाता है।
एलेसेंड्रो रूरो

5

यदि आप निर्माता को एनोटेट करना शुरू करते हैं, तो आपको सभी फ़ील्ड एनोटेट करना होगा।

ध्यान दें, मेरे Staff.name फ़ील्ड को JSON स्ट्रिंग में "ANOTHER_NAME" पर मैप किया गया है।

     String jsonInString="{\"ANOTHER_NAME\":\"John\",\"age\":\"17\"}";
     ObjectMapper mapper = new ObjectMapper();
     Staff obj = mapper.readValue(jsonInString, Staff.class);
     // print to screen

     public static class Staff {
       public String name;
       public Integer age;
       public Staff() {         
       }        

       //@JsonCreator - don't need this
       public Staff(@JsonProperty("ANOTHER_NAME") String   n,@JsonProperty("age") Integer a) {
        name=n;age=a;
       }        
    }

4

आपको एहसास होना चाहिए कि जैक्सन ने डीरियलाइज़ेशन के लिए कौन से विकल्प उपलब्ध हैं। जावा में, विधि तर्क नाम संकलित कोड में मौजूद नहीं हैं। यही कारण है कि जैक्सन आम तौर पर पहले से ही सेट की गई सभी चीजों के साथ एक अच्छी तरह से परिभाषित वस्तु बनाने के लिए निर्माणकर्ताओं का उपयोग नहीं कर सकता है।

इसलिए, यदि कोई खाली कंस्ट्रक्टर है और वहां पर बसने वाले भी हैं, तो वह खाली कंस्ट्रक्टर का उपयोग करता है। यदि कोई बसने वाला नहीं है, तो इसे करने के लिए कुछ काले जादू (प्रतिबिंब) का उपयोग किया जाता है।

यदि आप जैक्सन के साथ एक कंस्ट्रक्टर का उपयोग करना चाहते हैं, तो आपको उनके जवाब में @PiersyP द्वारा उल्लिखित एनोटेशन का उपयोग करना होगा। आप एक बिल्डर पैटर्न का उपयोग भी कर सकते हैं। यदि आप कुछ अपवादों का सामना करते हैं, तो सौभाग्य। जैक्सन में त्रुटि से निपटने में बड़ा समय लगता है, यह समझना मुश्किल है कि त्रुटि संदेशों में अस्पष्टता है।


जिस कारण से आपको "डिफ़ॉल्ट नो लॉजिक कंस्ट्रक्टर" फूक्लेस () की आवश्यकता है, क्योंकि संभावना है कि स्प्रिंग जावाबिन स्पेसिफिकेशन का अनुसरण करता है, जिसके कारण वस्तुओं को क्रमबद्ध और विचलित करते समय स्वचालित रूप से मार्शलिंग और अनमरशालिंग के लिए काम करना पड़ता है।
atom88

खैर, बाइनरी स्ट्रीम में जावा सीरियललाइज़ेशन और डिसेरिएलाइज़ेशन वैसे भी सवाल नहीं है। इसलिए यह केवल अच्छा है कि जैक्सन डिसरिज़लाइज़ेशन के साथ उपयोग किए जाने वाले कई पैटर्न प्रदान करता है। मुझे विशेष रूप से बिल्डर पैटर्न पसंद है क्योंकि यह परिणामी वस्तु को अपरिवर्तनीय बनाने की अनुमति देता है।
वल्सेक

3

पिछले प्रकाशन के बारे में मुझे वही समस्या थी जहाँ लोम्बोक १.१ I का उपयोग करते हुए। * समस्या उत्पन्न की।

मेरा समाधान @NoArgsConstructor (मापदंडों के बिना निर्माणकर्ता) को जोड़ना था, क्योंकि @Data में डिफ़ॉल्ट @RequiredArgsConstructor (मापदंडों के साथ कंस्ट्रक्टर) शामिल है।

लोंबोक डॉक्यूमेंटेशन https://projectlombok.org/features/all

इससे समस्या का समाधान होगा:

package example.counter;

import javax.validation.constraints.NotNull;

import lombok.Data;

@Data
@NoArgsConstructor
public class CounterRequest {
    @NotNull
    private final Integer int1;

    @NotNull
    private final Integer int2;
}

0

कस्टम जैकसन धारावाहिकों / Deserializers असफल भी समस्या हो सकती है। हालांकि यह आपका मामला नहीं है, यह ध्यान देने योग्य है।

मुझे एक ही अपवाद का सामना करना पड़ा और यह मामला था।


0

मेरे लिए, यह काम करता था, लेकिन पुस्तकालयों को अपग्रेड करने से यह समस्या प्रकट हुई। समस्या इस तरह एक वर्ग था:

package example.counter;

import javax.validation.constraints.NotNull;

import lombok.Data;

@Data
public class CounterRequest {
    @NotNull
    private final Integer int1;

    @NotNull
    private final Integer int2;
}

लुम्बोक का उपयोग करना:

<dependency>
    <groupId>org.projectlombok</groupId>
    <artifactId>lombok</artifactId>
    <version>1.18.0</version>
</dependency>

पीछे पड़ना

<dependency>
    <groupId>org.projectlombok</groupId>
    <artifactId>lombok</artifactId>
    <version>1.16.10</version>
</dependency>

मुद्दा तय किया। निश्चित रूप से क्यों नहीं, लेकिन भविष्य के लिए इसका दस्तावेज बनाना चाहता था।

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.