সিরিয়ালাইজেশন এবং deserialization সময় JSON সম্পত্তি বিভিন্ন নাম


149

এটি কি সম্ভব: ক্লাসে একটি ক্ষেত্র থাকলেও জ্যাকসন লাইব্রেরিতে সিরিয়ালাইজেশন / ডিসিরিয়ালাইজেশনের সময় এর বিভিন্ন নাম থাকতে পারে?

উদাহরণস্বরূপ, আমার কাছে "Coordiantes" ক্লাস রয়েছে।

class Coordinates{
  int red;
}

জেএসওএন থেকে ডিসিরিয়ালাইজেশনের জন্য এই জাতীয় ফর্ম্যাট রাখতে চান:

{
  "red":12
}

তবে যখন আমি বস্তুটিকে সিরিয়ালাইজ করব, ফলাফলটি এর মতো হওয়া উচিত:

{
  "r":12
}

আমি @JsonPropertyগেটর এবং সেটার উভয় (বিভিন্ন মান সহ) এ টীকাগুলি প্রয়োগ করে এটি প্রয়োগ করার চেষ্টা করেছি :

class Coordiantes{
    int red;

    @JsonProperty("r")
    public byte getRed() {
      return red;
    }

    @JsonProperty("red")
    public void setRed(byte red) {
      this.red = red;
    }
}

তবে আমি একটি ব্যতিক্রম পেয়েছি:

org.codehaus.jackson.map.exc.UnrecognisedPropertyException: অচেনা ক্ষেত্র "লাল"

উত্তর:


203

সবেমাত্র পরীক্ষিত এবং এটি কাজ করে:

public class Coordinates {
    byte red;

    @JsonProperty("r")
    public byte getR() {
      return red;
    }

    @JsonProperty("red")
    public void setRed(byte red) {
      this.red = red;
    }
}

ধারণাটি হল যে পদ্ধতির নামগুলি আলাদা হওয়া উচিত, তাই জ্যাকসন এটিকে এক ক্ষেত্র হিসাবে নয়, আলাদা ক্ষেত্র হিসাবে পার্স করে।

এখানে পরীক্ষার কোডটি রয়েছে:

Coordinates c = new Coordinates();
c.setRed((byte) 5);

ObjectMapper mapper = new ObjectMapper();
System.out.println("Serialization: " + mapper.writeValueAsString(c));

Coordinates r = mapper.readValue("{\"red\":25}",Coordinates.class);
System.out.println("Deserialization: " + r.getR());

ফলাফল:

Serialization: {"r":5}
Deserialization: 25

Jaxb সঙ্গে একই সম্ভব?
চুই পেংফেই 崔鹏飞

38

আপনি ব্যবহার করতে পারেন @jsonAliasযা জ্যাকসন ২.৯.০ এ প্রবর্তিত হয়েছে

উদাহরণ:

public class Info {
  @JsonAlias({ "red" })
  public String r;
}

এটি rসিরিয়ালাইজেশনের সময় ব্যবহার করে, তবে redডিসিরিয়ালেসনের সময় একটি উপকরণ হিসাবে দেয় as rযদিও এটি এখনও ডিসেরায়ালাইজড হতে দেয় ।


8
@JsonAlias ডকুমেন্টেশন স্পষ্টভাবে এটা যে যুক্তরাষ্ট্রের has no effect during serialization where primary name is always used। ওপি যা চায় তা নয়।
জাইরো দেগ্রিয়াজ

3
@XaeroDegreaz আমি @Asura মানে, যা আপনি ব্যবহার করতে পারেন rপ্রাথমিক নামের কিন্তু redজন্য @JsonAlias, যা এটি ধারাবাহিকভাবে করতে পারবেন r, কিন্তু যোগ reddeserialization উপর স্বীকৃত হবে। এটি দিয়ে এনেট করা @JsonProperty("r")এবং অতিরিক্ত @JsonAlias("red")প্রদত্ত সমস্যার জন্য সূক্ষ্মভাবে কাজ করা উচিত।
জেরোট

16

আপনার সম্পত্তিটি deserialization , এবং সিরিয়ালাইজেশন নিয়ন্ত্রণ করতে যথাক্রমে আপনি @ JsonSetter , এবং @ JsonGetter এর সংমিশ্রণটি ব্যবহার করতে পারেন । এটি আপনাকে স্ট্যান্ডার্ডাইজড গেটর এবং সেটার পদ্ধতির নামগুলি রাখতে দেয় যা আপনার আসল ক্ষেত্রের নামের সাথে মিল রাখে।

import com.fasterxml.jackson.annotation.JsonSetter;    
import com.fasterxml.jackson.annotation.JsonGetter;

class Coordinates {
    private int red;

    //# Used during serialization
    @JsonGetter("r")
    public int getRed() {
        return red;
    }

    //# Used during deserialization
    @JsonSetter("red")
    public void setRed(int red) {
        this.red = red;
    }
}

15

আমি দুটি পৃথক গেটার / সেটটার জোড়কে একটি ভেরিয়েবলের সাথে আবদ্ধ করব:

class Coordinates{
    int red;

    @JsonProperty("red")
    public byte getRed() {
      return red;
    }

    public void setRed(byte red) {
      this.red = red;
    }

    @JsonProperty("r")
    public byte getR() {
      return red;
    }

    public void setR(byte red) {
      this.red = red;
    }
}

13
তবে এই ক্ষেত্রে সিরিয়ালাইজেশন চলাকালীন আমরা একই মানের সাথে "r" এবং "red" উভয় বৈশিষ্ট্যই পেয়ে যাব।
কিআরচ

আপনি কীভাবে প্রক্রিয়াজাত করতে চান না সেই পদ্ধতিগুলিতে @ জসন এই বিষয়টিকে সমাধান করবে
স্টিফান

আজকাল আরও সুবিধাজনক টিকা রয়েছে: @JsonGetterএবং @JsonSetter। সুতরাং একজন সিরিয়ালাইজার কীভাবে আচরণ করবে তা ঠিক সেট করতে পারেন।
ডিআরসিবি

6

সাধারণ গিটার / সেটার জুটি পাওয়া সম্ভব। আপনাকে কেবল অ্যাক্সেস মোডটি ভিতরে নির্দিষ্ট করতে হবে@JsonProperty

এখানে তার জন্য ইউনিট পরীক্ষা দেওয়া হল:

public class JsonPropertyTest {

  private static class TestJackson {

    private String color;

    @JsonProperty(value = "device_color", access = JsonProperty.Access.READ_ONLY)
    public String getColor() {
      return color;
    };

    @JsonProperty(value = "color", access = JsonProperty.Access.WRITE_ONLY)
    public void setColor(String color) {
      this.color = color;
    }

  }

  @Test
  public void shouldParseWithAccessModeSpecified() throws Exception {
    String colorJson = "{\"color\":\"red\"}";
    ObjectMapper mapper = new ObjectMapper();
    TestJackson colotObject = mapper.readValue(colorJson, TestJackson.class);

    String ser = mapper.writeValueAsString(colotObject);
    System.out.println("Serialized colotObject: " + ser);
  }
}

আমি নিম্নলিখিত হিসাবে আউটপুট পেয়েছি:

Serialized colotObject: {"device_color":"red"}

5

সমাধান হিসাবে আমি যা প্রত্যাশা করছিলাম এটি ছিল না (যদিও এটি বৈধ ব্যবহারের ক্ষেত্রে)। আমার প্রয়োজনটি ছিল একটি বিদ্যমান বগী ক্লায়েন্ট (একটি মোবাইল অ্যাপ যা ইতিমধ্যে প্রকাশিত হয়েছে) বিকল্প নাম ব্যবহার করার অনুমতি দেয়।

সমাধানটি এর মতো একটি পৃথক সেটার পদ্ধতি সরবরাহের মধ্যে রয়েছে:

@JsonSetter( "r" )
public void alternateSetRed( byte red ) {
    this.red = red;
}

2

আমি এটি একটি পুরানো প্রশ্ন জানি কিন্তু আমার জন্য আমি এটি কাজ করতে পেরেছিলাম যখন আমি বুঝতে পারি যে এটি গসন লাইব্রেরির সাথে সাংঘর্ষিক তাই আপনি যদি জিসন ব্যবহার করছেন তবে আশার @SerializedName("name")পরিবর্তে ব্যবহার করুন @JsonProperty("name")এটি সাহায্য করবে


2

সঙ্গে টিকা @JsonAliasযা উল্লেখ ছাড়াই জ্যাকসন 2.9+ সঙ্গে পরিচয় করিয়ে দেন পেয়েছিলাম @JsonPropertyআইটেমের উপর একটির বেশি ওরফে (ক JSON সম্পত্তি জন্য বিভিন্ন নাম) কাজ করে জরিমানা দিয়ে deserialized হবে।

আমি com.fasterxml.jackson.annotation.JsonAliasপ্যাকেজ ধারাবাহিকতা জন্য ব্যবহারcom.fasterxml.jackson.databind.ObjectMapper আমার ব্যবহারের ক্ষেত্রে জন্য ব্যবহার করেছি।

যেমন:

@Data
@Builder
public class Chair {

    @JsonAlias({"woodenChair", "steelChair"})
    private String entityType;

}


@Test
public void test1() {

   String str1 = "{\"woodenChair\":\"chair made of wood\"}";
   System.out.println( mapper.readValue(str1, Chair.class));
   String str2 = "{\"steelChair\":\"chair made of steel\"}";
   System.out.println( mapper.readValue(str2, Chair.class));

}

ঠিক কাজ করে।


1

তারা অবশ্যই এটিকে একটি বৈশিষ্ট্য হিসাবে অন্তর্ভুক্ত করেছে, কারণ এখন @JsonPropertyআপনি কীভাবে প্রত্যাশা করবেন তার ঠিকঠাক এবং সেটটার ফলাফলের জন্য আলাদা করে সেট করে (একই ক্ষেত্রের সিরিয়ালাইজেশন এবং deserialization সময় বিভিন্ন সম্পত্তি নাম)। জ্যাকসন সংস্করণ 2.6.7


0

এটি করার জন্য আপনি সিরিয়ালাইজ ক্লাস লিখতে পারেন:

public class Symbol

{
     private String symbol;

     private String name;

     public String getSymbol() {
        return symbol;
    }
    public void setSymbol(String symbol) {
        this.symbol = symbol;
    }    
    public String getName() {
        return name;
    }    
    public void setName(String name) {
        this.name = name;
    }
}
public class SymbolJsonSerializer extends JsonSerializer<Symbol> {

    @Override
    public void serialize(Symbol symbol, JsonGenerator jgen, SerializerProvider serializers) throws IOException, JsonProcessingException {
        jgen.writeStartObject();

        jgen.writeStringField("symbol", symbol.getSymbol());
         //Changed name to full_name as the field name of Json string
        jgen.writeStringField("full_name", symbol.getName());
        jgen.writeEndObject(); 
    }
}
            ObjectMapper mapper = new ObjectMapper();

            SimpleModule module = new SimpleModule();
            module.addSerializer(Symbol.class, new SymbolJsonSerializer());
            mapper.registerModule(module); 

            //only convert non-null field, option...
            mapper.setSerializationInclusion(Include.NON_NULL); 

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