আমি জ্যাকসনকে এমন কোনও সম্পত্তি উপেক্ষা করার জন্য কীভাবে বলতে পারি যার জন্য উত্স কোডের উপর আমার নিয়ন্ত্রণ নেই?


112

দীর্ঘ গল্প সংক্ষেপে, আমার সত্তাগুলির মধ্যে একটিতে জ্যামিতি সংগ্রহ রয়েছে যা আপনি যখন "গেটবাউন্ডারি" বলবেন তখন একটি ব্যতিক্রম ছুঁড়ে মারবে (কেন এটি অন্য একটি বই, কারণ এখন বলি এটি এইভাবে কাজ করে)।

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

ধন্যবাদ!

উত্তর:


168

আপনি জ্যাকসন মিক্সিন ব্যবহার করতে পারেন । উদাহরণ স্বরূপ:

class YourClass {
  public int ignoreThis() { return 0; }    
}

এই মিশ্রণ দিয়ে

abstract class MixIn {
  @JsonIgnore abstract int ignoreThis(); // we don't need it!  
}

এর সাথে:

objectMapper.getSerializationConfig().addMixInAnnotations(YourClass.class, MixIn.class);

সম্পাদনা:

মন্তব্যে ধন্যবাদ, জ্যাকসন 2.5+ এর সাথে, এপিআই পরিবর্তন হয়েছে এবং এর সাথে কল করা উচিত objectMapper.addMixIn(Class<?> target, Class<?> mixinSource)


1
এবং যদি সম্পত্তিটি মেশিন উত্পন্ন হয় এবং এর নামে অসমর্থিত অক্ষর রয়েছে? '@' পছন্দ? জেভিএম এটির অনুমতি দেয় তবে জাভা সংকলক তা দেয় না। জ্যাকসনের কি এর সমাধান আছে?
চিহ্নিত করুন

3
এবং objectMapper.addMixInAnnotations(Class<?> target, Class<?> mixinSource);
জ্যাকসন

আমি গেটারের পরিবর্তে সম্পত্তিটির নাম উল্লেখ করে কীভাবে উপেক্ষা করব?
এরান মোরাড

68

অন্য একটি সম্ভাবনা হ'ল, যদি আপনি সমস্ত অজানা বৈশিষ্ট্য উপেক্ষা করতে চান তবে আপনি ম্যাপারটি নীচের হিসাবে কনফিগার করতে পারেন:

mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);

5
এটি দুর্দান্ত হবে যদি আমরা কেবলমাত্র বৈশিষ্ট্যগুলিকে উপেক্ষা করার জন্য অবজেক্টম্যাপারটি কনফিগার করতে পারি। অর্থাত্ 'মাইফিল্ড' না বলে সমস্ত নতুন / অজানা ক্ষেত্রের ব্যতিক্রমের প্রতিবেদন করুন। এর মতো কিছুmapper.configure(DeserializationFeature.failOnUnknownPropertiesExcep(new String[] {"myField"}));
এমএস_27

মনে রাখবেন যে এটি পাঠক without()হিসাবে যেমন ব্যবহার করে কনফিগার করা যায়:mapper.reader().without(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES)
ড্রু স্টিফেন্স

আমি এই প্রক্রিয়াটি ব্যবহারের বিরুদ্ধে দৃ strongly়ভাবে পরামর্শ দেব। জ্যাকসনের "কঠোর" মানসিকতা, অজানা / হাতছাড়া ক্ষেত্রগুলিতে ত্রুটি উত্থাপনের অন্যতম কারণ এটি জাভা সম্পর্কিত স্ট্যাটিকালি টাইপড / কম্পাইল-টাইম-এনালাইসড প্রকৃতির সাথে মেলে। পরিবর্তে উপেক্ষিত ক্ষেত্রগুলির একটি নির্দিষ্ট সেট পরিচালনা করা থেকে অপ্ট আউট করা ভাল।
পার লুন্ডবার্গ

26

জাভা ক্লাস ব্যবহার করা

new ObjectMapper().configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false)

টীকাগুলি ব্যবহার করা হচ্ছে

@JsonIgnoreProperties(ignoreUnknown=true)

11

টীকাগুলি ভিত্তিক পদ্ধতির আরও ভাল। তবে কখনও কখনও ম্যানুয়াল অপারেশন প্রয়োজন হয়। এই উদ্দেশ্যে আপনি অবজেক্ট রাইটার পদ্ধতি ছাড়াই ব্যবহার করতে পারেন ।

ObjectMapper mapper   = new ObjectMapper().configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false)
ObjectWriter writer   = mapper.writer().withoutAttribute("property1").withoutAttribute("property2");
String       jsonText = writer.writeValueAsString(sourceObject);

9
এই পদ্ধতিরটি আমার পক্ষে কাজ করে না, তবে মিশ্রণটি তা করে। সিরিয়ালাইজেশনের পরেও আমি উপেক্ষিত বৈশিষ্ট্যগুলি পেয়েছি। অ্যাট্রিবিউট () ছাড়াই কেন আমাদের মিক্সিন থাকবে?
এরান মোরাড

9

ইতিমধ্যে উল্লিখিত হিসাবে মিক্স টীকা এখানে বেশ ভাল কাজ করে। প্রতি-সম্পত্তি @JsonIgnore এর বাইরে আর একটি সম্ভাবনা হ'ল আপনার যদি এমন কোনও ধরণের থাকে যা কখনই অন্তর্ভুক্ত করা উচিত না হয় তবে @ JsonIgnoreType ব্যবহার করুন (অর্থাত্ জ্যামিত্রি সংগ্রহের সমস্ত বৈশিষ্ট্য উপেক্ষা করা উচিত)। তারপরে আপনি এটি সরাসরি যুক্ত করতে পারেন (যদি আপনি টাইপটি নিয়ন্ত্রণ করেন), বা মিক্স-ইন ব্যবহার করে, যেমন:

@JsonIgnoreType abstract class MixIn { }
// and then register mix-in, either via SerializationConfig, or by using SimpleModule

আপনার যদি অনেকগুলি ক্লাস থাকে যেগুলিতে একটি একক 'IgnoredType getContext ()' অ্যাকসেসর বা তাই (এটি অনেক ফ্রেমওয়ার্কের ক্ষেত্রে) থাকে তবে এটি আরও সুবিধাজনক হতে পারে if


5

আমার একই রকম সমস্যা ছিল তবে এটি হাইবারনেটের দ্বি-দিকনির্দেশক সম্পর্কের সাথে সম্পর্কিত। আমি সম্পর্কের এক দিকটি প্রদর্শন করতে চেয়েছিলাম এবং আমি কী দৃষ্টিভঙ্গি করছি তার উপর নির্ভর করে প্রোগ্রামগতভাবে অন্যটিকে অগ্রাহ্য করতে চাই। যদি আপনি এটি না করতে পারেন তবে আপনি শেষ বাজে StackOverflowException। উদাহরণস্বরূপ, আমার যদি এই জিনিসগুলি থাকে

public class A{
  Long id;
  String name;
  List<B> children;
}

public class B{
  Long id;
  A parent;
}

আমি প্রোগ্রামেটিক্যালি উপেক্ষা করার চাইবেন parentবি মাঠে যদি আমি একটি দিকে তাকিয়ে করা হয়েছে, এবং উপেক্ষা childrenএকটি মাঠে যদি আমি বি এ খুঁজছেন সেটা

আমি এটি করতে মিক্সিনগুলি ব্যবহার শুরু করেছি, তবে এটি খুব দ্রুত ভয়ঙ্কর হয়ে ওঠে; আপনার কাছে প্রচুর অকেজো ক্লাস রয়েছে যা কেবলমাত্র ডেটা ফর্ম্যাট করার জন্য বিদ্যমান exist এটিকে ক্লিনার উপায়ে পরিচালনা করতে আমি নিজের সিরিয়ালাইজারটি লিখে শেষ করেছি: https://github.com/monitorjbl/json-view

এটি আপনাকে কর্মক্ষেত্রে কোন ক্ষেত্রগুলি উপেক্ষা করতে হবে তা প্রোগ্রামিকভাবে নির্দিষ্ট করতে দেয়:

ObjectMapper mapper = new ObjectMapper();
SimpleModule module = new SimpleModule();
module.addSerializer(JsonView.class, new JsonViewSerializer());
mapper.registerModule(module);

List<A> list = getListOfA();
String json = mapper.writeValueAsString(JsonView.with(list)
    .onClass(B.class, match()
        .exclude("parent")));

এটি আপনাকে ওয়াইল্ডকার্ড ম্যাথারগুলির মাধ্যমে খুব সরলীকৃত দর্শন সহজেই নির্দিষ্ট করতে দেয়:

String json = mapper.writeValueAsString(JsonView.with(list)
    .onClass(A.class, match()
        .exclude("*")
         .include("id", "name")));

আমার মূল ক্ষেত্রে, এই জাতীয় মতামতগুলির প্রয়োজন ছিল পিতামাতার / সন্তানের সম্পর্কে সর্বাধিক ন্যূনতম প্রদর্শন করা, তবে এটি আমাদের ভূমিকা-ভিত্তিক সুরক্ষার জন্যও কার্যকর হয়ে ওঠে। অবজেক্ট সম্পর্কে কম তথ্য ফেরতের জন্য অবজেক্টগুলির কম সুবিধাযুক্ত দৃষ্টিভঙ্গি প্রয়োজন।

এগুলি সবই সিরিয়ালাইজার থেকে এসেছে তবে আমি আমার অ্যাপটিতে স্প্রিং এমভিসি ব্যবহার করছিলাম। এই কেসগুলি সঠিকভাবে পরিচালনা করতে এটি পেতে, আমি একটি ইন্টিগ্রেশন লিখেছি যা আপনি বিদ্যমান স্প্রিং কন্ট্রোলার ক্লাসে ফেলে যেতে পারেন:

@Controller
public class JsonController {
  private JsonResult json = JsonResult.instance();
  @Autowired
  private TestObjectService service;

  @RequestMapping(method = RequestMethod.GET, value = "/bean")
  @ResponseBody
  public List<TestObject> getTestObject() {
    List<TestObject> list = service.list();

    return json.use(JsonView.with(list)
        .onClass(TestObject.class, Match.match()
            .exclude("int1")
            .include("ignoredDirect")))
        .returnValue();
  }
}

উভয়ই মাভেন সেন্ট্রালে উপলব্ধ। আমি আশা করি এটি অন্য কাউকে সাহায্য করবে, এটি জ্যাকসনের একটি বিশেষভাবে কুৎসিত সমস্যা যা আমার ক্ষেত্রে ভাল সমাধান করতে পারে নি।


কি জন্য আমদানি Match.match()?
পাশুপতি রাজনীকণিক

2

আপনি যদি কোনও শ্রেণীর জন্য নির্দিষ্ট বৈশিষ্ট্যগুলি সর্বদা বাদ দিতে চান তবে আপনি setMixInResolverপদ্ধতিটি ব্যবহার করতে পারেন :

    @JsonIgnoreProperties({"id", "index", "version"})
    abstract class MixIn {
    }

    mapper.setMixInResolver(new ClassIntrospector.MixInResolver(){
        @Override
        public Class<?> findMixInClassFor(Class<?> cls) {
            return MixIn.class;  
        }

        @Override
        public ClassIntrospector.MixInResolver copy() {
            return this;
        }
    });

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