জ্যাকসন + বিল্ডার প্যাটার্ন?


89

আমি চাই যে জ্যাকসন নিম্নোক্ত নির্মাণকারীর সাহায্যে একটি শ্রেণীর deserialize করুন:

public Clinic(String name, Address address)

প্রথম যুক্তিটি ডিসরিয়াজিং করা সহজ। সমস্যাটি হ'ল ঠিকানাটি সংজ্ঞায়িত করা হয়:

public class Address {
  private Address(Map<LocationType, String> components)
  ...

  public static class Builder {
    public Builder setCity(String value);
    public Builder setCountry(String value);
    public Address create();
  }
}

এবং এটি নির্মিত হয়: new Address.Builder().setCity("foo").setCountry("bar").create();

ঠিকানাটি নিজেই তৈরি করার জন্য জ্যাকসনের কাছ থেকে কী-মূল্যের জোড়গুলি পাওয়ার কোনও উপায় আছে? বিকল্পভাবে, জ্যাকসনকে নিজেই বিল্ডার শ্রেণি ব্যবহার করার উপায় আছে কি?

উত্তর:


142

যতক্ষণ আপনি জ্যাকসন 2+ ব্যবহার করছেন, ততক্ষণে এখন এটির সমর্থনে তৈরি

প্রথমে আপনার Addressক্লাসে এই টিকাটি যুক্ত করতে হবে :

@JsonDeserialize(builder = Address.Builder.class)

তারপরে আপনার Builderক্লাসে এই টিকাটি যুক্ত করতে হবে :

@JsonPOJOBuilder(buildMethodName = "create", withPrefix = "set")

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

সম্পূর্ণ উদাহরণ:

@JsonDeserialize(builder = Address.Builder.class)
public class Address
{
  private Address(Map<LocationType, String> components)
  ...

  @JsonPOJOBuilder(buildMethodName = "create", withPrefix = "set")
  public static class Builder
  {
    public Builder setCity(String value);
    public Builder setCountry(String value);
    public Address create();
  }
}

14
যদি @JsonPOJOBuilderএকসাথে টীকা থেকে মুক্তি পাওয়ার ইচ্ছা হয় , তবে "বিল্ড" করার জন্য "তৈরি করুন" নামকরণ করুন এবং প্রতিটি বিল্ডার সেটার দিয়ে এনোটেট করুন @JsonProperty
স্যাম বেরি

এটা সোনার। ধন্যবাদ
মুকুল গোয়েল

এটি এখন পুরানো হয়, Lombok 1.18.4 সঙ্গে আপনি ব্যবহার করতে পারেন @Jacksonizedযা ভেতরের রচয়িতা ও একটি একক জিনিস সঙ্গে জ্যাকসন টীকা প্রতিস্থাপন
Randakar

@ রান্ডাকর আমি এটিকে পুরানো বলে মনে করি না কারণ ক) @Jackonized লম্বোকের একটি সবেমাত্র প্রকাশিত পরীক্ষামূলক বৈশিষ্ট্য। অযথা পরীক্ষামূলক বৈশিষ্ট্যগুলি গ্রহণের জন্য উত্সাহ দেওয়া ভাল ধারণা বলে আমি মনে করি না। খ) প্রশ্নটি লোমবকের উল্লেখ বা ব্যবহার করে না। আমি মনে করি না যে অযথা সমস্যা সমাধানের জন্য নির্ভরতা প্রবর্তন করা ভাল ধারণা।
রূপ্ট ম্যাডেন-অ্যাবট

20

@ রুপার্ট ম্যাডেন-অ্যাবোটের উত্তর কাজ করে। তবে, যদি আপনার একটি ডিফল্ট নির্মাতা থাকে, যেমন,

Builder(String city, String country) {...}

তারপরে আপনার নীচের মত প্যারামিটারগুলি টিকা দেওয়া উচিত:

@JsonCreator
Builder(@JsonProperty("city")    String city, 
        @JsonProperty("country") String country) {...}

9

একটি সমাধান যা এই ক্ষেত্রে আমার জন্য উপযুক্ত ছিল (আমি "লম্বোক" বিল্ডার টিকা ব্যবহার করেছি)।

@Getter
@Builder(builderMethodName = "builder")
@NoArgsConstructor(access = AccessLevel.PRIVATE)
@AllArgsConstructor(access = AccessLevel.PRIVATE)
@JsonAutoDetect(
    fieldVisibility = JsonAutoDetect.Visibility.ANY,
    creatorVisibility = JsonAutoDetect.Visibility.ANY
)

আমি আশা করি আপনার জন্যও দরকারী হবে।


এটি এখন পুরানো হয়, Lombok 1.18.4 সঙ্গে আপনি ব্যবহার করতে পারেন @Jacksonizedযা ভেতরের রচয়িতা ও একটি একক জিনিস সঙ্গে জ্যাকসন টীকা প্রতিস্থাপন
Randakar

7

আমি নিম্নলিখিতটি @ জসনডিজারিয়ালাইজ ব্যবহার করে এটি প্রয়োগ করেছি:

@JsonDeserialize(using = JacksonDeserializer.class)
public class Address
{...}

@JsonCachable
static class JacksonDeserializer extends JsonDeserializer<Address>
{
    @Override
    public Address deserialize(JsonParser parser, DeserializationContext context)
        throws IOException, JsonProcessingException
    {
        JsonToken token = parser.getCurrentToken();
        if (token != JsonToken.START_OBJECT)
        {
            throw new JsonMappingException("Expected START_OBJECT: " + token, parser.getCurrentLocation());
        }
        token = parser.nextToken();
        Builder result = new Builder();
        while (token != JsonToken.END_OBJECT)
        {
            if (token != JsonToken.FIELD_NAME)
            {
                throw new JsonMappingException("Expected FIELD_NAME: " + token, parser.getCurrentLocation());
            }
            LocationType key = LocationType.valueOf(parser.getText());

            token = parser.nextToken();
            if (token != JsonToken.VALUE_STRING)
            {
                throw new JsonMappingException("Expected VALUE_STRING: " + token, parser.getCurrentLocation());
            }
            String value = parser.getText();

            // Our Builder allows passing key-value pairs
            // alongside the normal setter methods.
            result.put(key, value);
            token = parser.nextToken();
        }
        return result.create();
    }
}

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

2

বিল্ডার প্যাটার্নটির জন্য বর্তমানে কোনও সমর্থন নেই, যদিও এটি বেশ আগেই অনুরোধ করা হয়েছিল (এবং শেষ অবধি জিরা ইস্যুতে http://jira.codehaus.org/browse/JACKSON-469 দায়ের করা হয়েছিল) - এটি এমন কিছু যা যুক্ত করা যেতে পারে 1.8 মুক্তির জন্য পর্যাপ্ত চাহিদা থাকলে (জিরায় ভোট দেওয়ার বিষয়টি নিশ্চিত করুন!)। এটি একটি যুক্তিসঙ্গত অতিরিক্ত বৈশিষ্ট্য, এবং কেবলমাত্র সময় বিকাশকারীদের পরিমাণ অনুসারে বিলম্ব করে। তবে আমি মনে করি এটি দুর্দান্ত সংযোজন হবে।


4
কোডাউসের আর জিরা উপলব্ধ নেই তবে সংযুক্ত সমস্যাটি এখানে বর্ণিত হয়েছে: উইকি.ফাস্টারএমএমলাল
পল

জ্যাকসন ২.২ এর মতো এমন কিছু ক্ষেত্রে বিল্ডার প্যাটার্নের জন্য সমর্থন দীর্ঘকাল থেকেই যুক্ত করা হয়েছে।
স্ট্যাক্সম্যান

2

এটি আমার পক্ষে কাজ করেছে: @ নোআরগস কনস্ট্রাক্টর এর একমাত্র ত্রুটি, এটি আবার = নতুন এডিটিও () করতে পারে। তবে, আরে, আমি কোনওভাবেই কোড কোড পুলিশ পছন্দ করি না, আমাকে কীভাবে কোনও কোড ব্যবহার করতে হবে তা বলার জন্য :-) সুতরাং, আমার পোজো ডিটিওএস আপনার পছন্দ মতো ব্যবহার করুন। নির্মাতার সাথে বা ছাড়াই। আমি পরামর্শ দিচ্ছি: এটি কোনও বিল্ডারের সাথে করুন তবে আমার অতিথি হোন ...

@Data
@Builder
//Dont forget this! Otherwise no Jackson serialisation possible!
@NoArgsConstructor
@AllArgsConstructor
public class ADTO {
.....
}
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.