জসনম্যাপিংএক্সেপশন: টাইপ [সাধারণ ধরণের, শ্রেণি] এর জন্য উপযুক্ত কোন কনস্ট্রাক্টর পাওয়া যায় নি: জেএসএন অবজেক্ট থেকে ইনস্ট্যান্ট করতে পারবেন না


438

একটি JSON অনুরোধ পেতে এবং এটি প্রক্রিয়া করার চেষ্টা করার সময় আমি নিম্নলিখিত ত্রুটিটি পাচ্ছি:

org.codehaus.jackson.map.JsonMappingException: প্রকারের জন্য উপযুক্ত কোন কনস্ট্রাক্টর পাওয়া যায় নি [সাধারণ ধরণের, ক্লাস com.myweb.applesDO]: JSON অবজেক্ট থেকে ইনস্ট্যান্ট করতে পারবেন না (টাইপ তথ্য যুক্ত / সক্ষম করার দরকার আছে?)

আমি যে জেএসএনটি পাঠানোর চেষ্টা করছি তা এখানে:

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

কন্ট্রোলারে, আমার কাছে নিম্নলিখিত পদ্ধতির স্বাক্ষর রয়েছে:

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

অল অ্যাপলসডো অ্যাপলসডোর একটি মোড়ক:

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 কে জাভা বস্তুতে রূপান্তর করতে অক্ষম। জ্যাকসনকে JSON কে জাভা অবজেক্টে রূপান্তর করতে দয়া করে কনফিগারেশন প্যারামিটারে সহায়তা করুন। আমি স্প্রিং ফ্রেমওয়ার্ক ব্যবহার করছি।

সম্পাদনা: উপরের নমুনা শ্রেণিতে এই সমস্যা সৃষ্টি করছে এমন বড় বাগটি অন্তর্ভুক্ত করেছে - দয়া করে সমাধানের জন্য গৃহীত উত্তরটি দেখুন look


2
আমি উপরের কোডটিতে কোনও সাবক্ল্যাস দেখতে পাচ্ছি না, এই কোডটি কি আপনার চেষ্টা করছে বা আপনি একটি সহজ উদাহরণ তৈরি করছেন?
gkamal

এটি কীভাবে কাজ করে তার আরও কিছু ব্যাখ্যা সহ আমি একটি উত্তর যুক্ত করেছি। মূলত, আপনার বুঝতে হবে জাভা রানটাইমের সময় পদ্ধতির যুক্তির নাম রাখে না।
ভ্ল্যাক

উত্তর:


565

সুতরাং, অবশেষে বুঝতে পারি সমস্যাটি কী। আমি সন্দেহ করেছিলাম এটি কোনও জ্যাকসন কনফিগারেশন সমস্যা নয়।

আসলে সমস্যাটি অ্যাপলসডো ক্লাসে ছিল:

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() {
    }

}

কাস্টমটাইপ কোথা থেকে এসেছে তা আমি জানতে পারি। আমি এই জাতীয় কাঠামোর চেষ্টা করছি তবে আমি জাভাতে একেবারে নতুন।
andho

181
আপনি অভ্যন্তরীণ (নেস্টেড) ক্লাস সহ জ্যাকসন ব্যবহার করতে পারেন, সিরিয়ালাইজেশন এই ক্ষেত্রে ঠিক কাজ করে works একমাত্র হোঁচট খাচ্ছে যে deserialization সঠিকভাবে কাজ করার জন্য অভ্যন্তর শ্রেণিকে অবশ্যই "স্থিতিশীল" হিসাবে চিহ্নিত করতে হবে। ব্যাখ্যা এখানে দেখুন: cowtowncoder.com/blog/archives/2010/08/entry_411.html
জেপেনেল

3
কেউ দয়া করে ব্যাখ্যা করতে পারেন কেন এমন হয়? আমি খুব অনুরূপ ত্রুটি ছিল। ভেবেছি সমস্ত সঠিক নির্মাণকারীর জায়গায় রয়েছে, কিন্তু deserialize করতে পারেনি। এই পোস্টটি পড়ে আমি কেবল একটি ডামি কনস্ট্রাক্টর যুক্ত করার পরে এটি কাজ করেছিল।
ব্যবহারকারী 8658912

6
@ সুমন আমি এটিকে একটি ডামি কনস্ট্রাক্টর বলব না - এটি কেবলমাত্র ডিফল্ট নির্মাণকারী। এটি কেবল পুরোপুরি বৈধ নয়, তবে বিভিন্ন ধরণের জাভা বিন-প্রসেসিংয়ের জন্য প্রয়োজনীয়। (এবং, অবশ্যই, এটা আমাকে হোঁচট খেয়েছি :-)।)
fool4jesus

2
আপনি যদি ডিফল্ট কনস্ট্রাক্টর যুক্ত করতে না চান (যেমন, আপনি যখন অপরিবর্তনীয় বস্তুগুলির সাথে লেনদেন করছেন)। জসনক্রিটার টীকাটি ব্যবহার করে কোন কনস্ট্রাক্টর বা কারখানার পদ্ধতি অবজেক্টটি ইনস্ট্যান্ট করতে ব্যবহার করতে হবে।
রাহুল

375

এই কারণগুলির জন্য এটি ঘটে:

  1. আপনার অভ্যন্তর শ্রেণি স্থির হিসাবে সংজ্ঞায়িত করা উচিত

    private static class Condition {  //jackson specific    
    }
    
  2. এটি হতে পারে যে আপনি আপনার ক্লাসে কোনও ডিফল্ট কনস্ট্রাক্টর পেলেন না ( আপডেট: এটি মনে হয় না)

    private static class Condition {
        private Long id;
    
        public Condition() {
        }
    
        // Setters and Getters
    }
    
  3. এটি হতে পারে আপনার সেটারগুলি সঠিকভাবে সংজ্ঞায়িত হয় না বা দৃশ্যমান হয় না (যেমন ব্যক্তিগত সেটটার)


95
স্ট্যাটিক ক্লাস আমার ক্ষেত্রে পার্থক্য তৈরি করেছে। ধন্যবাদ!
jologar

3
এবং অবশ্যই, আপনি না , একটি খালি, নো-যুক্তি ডিফল্ট কন্সট্রাকটর ডিক্লেয়ার প্রয়োজন আপনার জন্য জাভা এটা আছে ! (যতক্ষণ না আপনি অন্য কোনও নির্মাণকারীর সংজ্ঞা দেন না))
জোনিক

1
@ জোনিক, ঠিক আছে! আমার উত্তরটি পুরান, যদি আমি সঠিক মনে করি, যেহেতু জ্যাকসন অভ্যন্তরীণ শ্রেণিতে যাওয়ার জন্য প্রতিবিম্বটি ব্যবহার করছেন, তাই আমি অনুমান করি যে এটির জন্য ডিফল্ট নির্মাতাকে সংজ্ঞায়িত করা দরকার ছিল (এটি নতুন সংস্করণের ক্ষেত্রেও নাও হতে পারে), তবে যেহেতু আমি নই নিশ্চিত যে আপনি সঠিক হতে পারে।
আজেফরাতি

6
হ্যাঁ, আমার অভিজ্ঞতা জ্যাকসন ২.৪.৪ এর সাথে রয়েছে: সত্যিই জাভার অন্তর্নিহিত ডিফল্ট নির্মাতা যথেষ্ট। আপনি স্পষ্টভাবে লিখতে নো args কন্সট্রাকটর প্রয়োজন শুধুমাত্র যদি আপনি সংজ্ঞায়িত করেছি অন্যান্য কনস্ট্রাকটর না যে নিতে আর্গুমেন্ট (অর্থাত যখন জাভা নো args আপনাকে এমন একটি তৈরি করে না)।
জোনিক

2
আমার সাথে, অচল শ্রেণি দিনটি বাঁচিয়েছিল।
সাইমন

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

আমি যখন এই সমস্যায় পড়েছিলাম, তখন এটি ডিও হিসাবে পরিবেশন করার জন্য একটি অভ্যন্তরীণ বর্গ ব্যবহার করার চেষ্টা করার ফলাফল ছিল। অভ্যন্তরীণ বর্গ তৈরির জন্য (নিঃশব্দে) বেষ্টনকারী শ্রেণীর একটি উদাহরণ প্রয়োজন - যা জ্যাকসনের কাছে উপলভ্য ছিল না।

এই ক্ষেত্রে, অভ্যন্তরীণ শ্রেণীটিকে নিজস্ব। জাভা ফাইলের দিকে নিয়ে যাওয়া সমস্যার সমাধান করে।


6
অভ্যন্তরীণ শ্রেণীটিকে নিজের। জাভা ফাইলের দিকে সরানো কাজ করে, স্ট্যাটিক সংশোধক যুক্ত করে @ বুলড্রিমের উত্তরে উল্লিখিত সমস্যাটিকেও সম্বোধন করে।
jums

20

সাধারণত এই ত্রুটিটি আসে কারণ আমরা ডিফল্ট কনস্ট্রাক্টর করি না তবে আমার ক্ষেত্রে সমস্যাটি কেবল প্যারেন্ট ক্লাসের অভ্যন্তরে অবজেক্ট ক্লাস তৈরি করার কারণে আসছিল। এটি আমার পুরো দিন নষ্ট করে দিয়েছে।


নেস্টেড ক্লাস করার জন্য এটি যথেষ্ট static
অলস

13

থাম্ব রুল : ম্যাপিং ক্লাস হিসাবে ব্যবহৃত প্রতিটি শ্রেণীর জন্য একটি ডিফল্ট কনস্ট্রাক্টর যুক্ত করুন। আপনি এই মিস করেছেন এবং সমস্যা উত্থাপিত!
কেবলমাত্র ডিফল্ট কনস্ট্রাক্টর যুক্ত করুন এবং এটির কাজ করা উচিত।


সুন্দর উত্তর .ধন্যবাদ। আমার দিনটি বাঁচিয়েছে।
স্টিভ

9

আপনি কি এই কাঠামো পরীক্ষা করতে পারেন? যদি আমি সঠিক মনে রাখি তবে আপনি এটি এইভাবে ব্যবহার করতে পারেন:

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

দ্বিতীয়ত, দয়া করে প্রতিটি শ্রেণিতে ডিফল্ট কনস্ট্রাক্টর যুক্ত করুন এটির সাহায্যও হতে পারে।


কাজ করছে না: নিম্নলিখিত ত্রুটি পাওয়া: "org.codehaus.jackson.map.exc.UnrecognisedPropertyException: অচেনা ক্ষেত্র & quot; আপেলসউকেস্ট & quot; (ক্লাস com.smartshop.dao.AllapplesDO), উপেক্ষা হিসাবে চিহ্নিত করা হয়নি"
লাকী মুরারি

পূর্বে এটি কমপক্ষে AllApplesDO এর জন্য ত্রুটির মধ্যে দিয়ে ব্যবহৃত হত না এবং কেবল বদ্ধ শ্রেণীর জন্য নিক্ষেপ করে .. এখন এটি প্রথম শ্রেণীর জন্য নিজেই ছুঁড়ে
ভাগ্যবান মুরারি

একটি ডিফল্ট নির্মাণকারী প্রয়োজন। ধন্যবাদ!
প্ল্যাঙ্কি

এটিকে সঠিক উত্তর হিসাবে বেছে নেওয়া উচিত নয়?
দ্রুত দাঁত

7

আমাদের মডেল ক্লাসে আপনাকে ডামি খালি কনস্ট্রাক্টর তৈরি করতে হবে j তাই জেএসন ম্যাপিংয়ের সময় এটি সেটার পদ্ধতিতে সেট করে।


এই ঠিক করা।
ডেভিড কোবিয়া

এটা আমার ক্ষেত্রেও আমার অবজেক্টের জন্য আমার অনেকগুলি আলাদা কনস্ট্রাক্টর ছিল এবং তাই আমি সবেমাত্র অন্য একটি খালি তৈরি করেছি যা সম্ভবত জ্যাকসনের দ্বারা ব্যবহৃত হয়ে যায়।
আলেসান্দ্রো রারো

5

আপনি যদি কনস্ট্রাক্টরকে টীকা দিতে শুরু করেন তবে আপনাকে অবশ্যই সমস্ত ক্ষেত্রকে টিকা দিতে হবে।

লক্ষ্য করুন, আমার স্টাফ.নাম ক্ষেত্রটি 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

জ্যাকসনের ডিসরিয়ালাইজেশনের জন্য কী কী বিকল্প রয়েছে তা আপনার অবশ্যই উপলব্ধি করতে হবে। জাভাতে, পদ্ধতির আর্গুমেন্টের নামগুলি সংকলিত কোডে উপস্থিত নেই। এজন্য জ্যাকসন ইতিমধ্যে সেট করা সমস্ত কিছু দিয়ে একটি সু-সংজ্ঞায়িত অবজেক্ট তৈরি করতে সাধারণত কনস্ট্রাক্টর ব্যবহার করতে পারবেন না।

সুতরাং, যদি খালি কনস্ট্রাক্টর থাকে এবং সেটারও থাকে তবে এটি খালি কনস্ট্রাক্টর এবং সেটার ব্যবহার করে। যদি কোনও সেটটার না থাকে তবে এটি করতে কিছু গা dark় যাদু (প্রতিচ্ছবি) ব্যবহৃত হয়।

আপনি যদি জ্যাকসনের সাথে কোনও কনস্ট্রাক্টর ব্যবহার করতে চান তবে আপনাকে অবশ্যই তার উত্তরটিতে @ পিয়ারসিপি দ্বারা উল্লিখিত টীকাগুলি ব্যবহার করতে হবে। আপনি একটি বিল্ডার প্যাটার্নও ব্যবহার করতে পারেন। আপনি যদি কিছু ব্যতিক্রম মুখোমুখি হন, সৌভাগ্য। জ্যাকসনের পরিচালনায় ত্রুটিটি বড় সময় চুষে দেয়, ত্রুটি বার্তাগুলিতে এই জিব্রিশটি বোঝা শক্ত।


আপনার "ডিফল্ট নো আর্গুমেন্ট কনস্ট্রাক্টর" ফুক্লাস () এর কারণ সম্ভবত স্প্রিং জাভাবিয়ান স্পেসিফিকেশন অনুসরণ করে, যা বস্তুগুলিকে সিরিয়ালাইজ এবং ডিসাইরিজাইজ করার সময় স্বয়ংক্রিয়ভাবে মার্শেলিং এবং আনমারশেলিংয়ের জন্য কাজ করা প্রয়োজন।
atom88

ঠিক আছে, জাভা সিরিয়ালাইজেশন এবং বাইনারি স্ট্রিমের deserialization প্রশ্ন যাইহোক, প্রশ্নটি নয়। সুতরাং এটি কেবল ভাল যে জ্যাকসন ডিজিজারাইজেশনের সাথে ব্যবহার করার জন্য একাধিক নিদর্শন সরবরাহ করে। আমি বিশেষত বিল্ডার প্যাটার্নটি পছন্দ করি কারণ এটি ফলস্বরূপ অবজেক্টটিকে পরিবর্তনযোগ্য হতে দেয়।
ভ্লাস্যাক

3

সর্বশেষ প্রকাশনাটি সম্পর্কে আমার একই সমস্যা ছিল যেখানে লোমবক ১.১18 ব্যবহার করা হয়েছিল * * সমস্যাটি উত্পন্ন করেছে।

আমার সমাধানটি ছিল @ NoArgsConstructor (পরামিতিবিহীন নির্মাণকারী) যুক্ত করা, যেহেতু @ ডেটা ডিফল্ট হিসাবে @RequiredArgsConstructor (পরামিতি সহ কনস্ট্রাক্টর) অন্তর্ভুক্ত রয়েছে।

lombok ডকুমেন্টেশন 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

কাস্টম জ্যাকসন সিরিয়ালাইজার / ডিসরিযালার্স ব্যর্থ হওয়াও সমস্যা হতে পারে। যদিও এটি আপনার ক্ষেত্রে না, এটি উল্লেখ করার মতো।

আমিও একই ব্যতিক্রমের মুখোমুখি হয়েছি এবং এটিই ছিল।


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>

ইস্যু স্থির। নিশ্চিত নয় কেন, তবে ভবিষ্যতের জন্য এটি নথিভুক্ত করতে চেয়েছিল।

আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.