নির্দিষ্ট ক্ষেত্রগুলির জন্য জ্যাকসন জেএসন কাস্টম সিরিয়ালাইজেশন


97

কাস্টম ফিল্ড স্তরের সিরিয়ালাইজেশন করার জন্য জ্যাকসন জেএসন প্রসেসর ব্যবহার করার কোনও উপায় আছে? উদাহরণস্বরূপ, আমি ক্লাস করতে চাই

public class Person {
    public String name;
    public int age;
    public int favoriteNumber;
}

অনুসরণ JSON সিরিয়ালায়িত:

{ "name": "Joe", "age": 25, "favoriteNumber": "123" }

মনে রাখবেন যে বয়স = 25 একটি সংখ্যা হিসাবে এনকোড হয়েছে যখন প্রিয় সংখ্যা = 123 স্ট্রিং হিসাবে এনকোড হয়েছে । বাক্সের বাইরে জ্যাকসন intএকটি সংখ্যায় মার্শাল । এই ক্ষেত্রে আমি চাই প্রিয় নম্বরটি একটি স্ট্রিং হিসাবে এনকোড করা হোক।


4
আমি জ্যাকসনের সাথে কাস্টম সিরিয়ালাইজার কীভাবে লিখব সে সম্পর্কে একটি পোস্ট লিখেছিলাম যা কারওর পক্ষে সহায়ক হতে পারে।
স্যাম বেরি

উত্তর:


110

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

public class Person {
    public String name;
    public int age;
    @JsonSerialize(using = IntToStringSerializer.class, as=String.class)
    public int favoriteNumber:
}


public class IntToStringSerializer extends JsonSerializer<Integer> {

    @Override
    public void serialize(Integer tmpInt, 
                          JsonGenerator jsonGenerator, 
                          SerializerProvider serializerProvider) 
                          throws IOException, JsonProcessingException {
        jsonGenerator.writeObject(tmpInt.toString());
    }
}

জাভা intআপনার Integerকাছে থেকে অটোবক্সিং পরিচালনা করবে।


4
জ্যাকসন-ডাটাবাইন্ড (কমপক্ষে ২.১.৩) ইতিমধ্যে বিশেষ টোস্ট্রিংশিরাইজার রয়েছে, আমার উত্তর দেখুন।
werupokz

@ কেভিনবুওয়ারসক্স আপনি কি আমার ডিসরিয়ালাইজিং সমস্যায় সহায়তা করতে পারেন ?
জেজেডি


এটি করার কোনও কম ভয়ঙ্কর উপায় আছে কি? পছন্দ Person implements ToJson?
জামেশফিশার 11

4
আমার ক্ষেত্রে, এটি as=String.classব্যবহৃত অংশগুলির কারণে এটি এমনকি ব্যর্থ হয়েছিল । @ কেভিন-বায়ারসক্স, আমি আপনার মন্তব্য আপডেট করার পরামর্শ দিচ্ছি, @ গ্যারেথল্যাটি যা বলেছিলেন তার সাথে মিল রেখে।
বার্ট

56

জ্যাকসন-ডাটাবাইন্ড (কমপক্ষে 2.1.3) বিশেষ ToStringSerializer( com.fasterxml.jackson.databind.ser.std.ToStringSerializer) সরবরাহ করে

উদাহরণ:

public class Person {
    public String name;
    public int age;
    @JsonSerialize(using = ToStringSerializer.class)
    public int favoriteNumber:
}

4
যেখানে স্ট্রিংকে একটি ইনটে রূপান্তর করতে হবে তার বিপরীতে কী হবে? আমি ToIntSerializer.class দেখতে পাচ্ছি না।
jEremyB

@jEremyB আপনাকে একটি কাস্টম
ড্রিউ স্টিফেন্স

টোস্ট্রিংশায়ারাইজার কাজ করে তবে ফ্লোটসায়ারাইজার এই বার্তাটি নিয়ে আসে: সামগ্রী লিখতে পারেনি: java.lang.Integer java.lang.Float- এ
আটকানো যায় না

13

জ্যাকসন-টীকাগুলি সরবরাহ করে @JsonFormatযা কাস্টম সিরিয়ালাইজার লেখার প্রয়োজন ছাড়াই প্রচুর কাস্টমাইজেশন পরিচালনা করতে পারে।

উদাহরণস্বরূপ, STRINGসংখ্যার প্রকারযুক্ত ক্ষেত্রের জন্য একটি আকারের জন্য অনুরোধ করলে সংখ্যাটিকে স্ট্রিং হিসাবে আউটপুট করা হবে

public class Person {
    public String name;
    public int age;
    @JsonFormat(shape = JsonFormat.Shape.STRING)
    public int favoriteNumber;
}

কাঙ্ক্ষিত আউটপুট ফলাফল হবে

{"name":"Joe","age":25,"favoriteNumber":"123"}

11

ক্ষেত্রের জন্য একটি @JsonPropertyটীকাযুক্ত গিটার যুক্ত করুন, যা একটি Stringপ্রদান করে favoriteNumber:

public class Person {
    public String name;
    public int age;
    private int favoriteNumber;

    public Person(String name, int age, int favoriteNumber) {
        this.name = name;
        this.age = age;
        this.favoriteNumber = favoriteNumber;
    }

    @JsonProperty
    public String getFavoriteNumber() {
        return String.valueOf(favoriteNumber);
    }

    public static void main(String... args) throws Exception {
        Person p = new Person("Joe", 25, 123);
        ObjectMapper mapper = new ObjectMapper();
        System.out.println(mapper.writeValueAsString(p)); 
        // {"name":"Joe","age":25,"favoriteNumber":"123"}
    }
}

8

আপনি যদি কোনও মন্তব্য দিয়ে আপনার মডেলকে দূষিত করতে না চান এবং কিছু কাস্টম ক্রিয়াকলাপ করতে চান, আপনি মিক্সিন ব্যবহার করতে পারেন।

ObjectMapper mapper = new ObjectMapper();
SimpleModule simpleModule = new SimpleModule();
simpleModule.setMixInAnnotation(Person.class, PersonMixin.class);
mapper.registerModule(simpleModule);

ওভাররাইড বয়স:

public abstract class PersonMixin {
    @JsonSerialize(using = PersonAgeSerializer.class)
    public String age;
}

বয়সের সাথে আপনার যা কিছু প্রয়োজন তা করুন:

public class PersonAgeSerializer extends JsonSerializer<Integer> {
    @Override
    public void serialize(Integer integer, JsonGenerator jsonGenerator, SerializerProvider serializerProvider) throws IOException {
        jsonGenerator.writeString(String.valueOf(integer * 52) + " months");
    }
}

3

সাহায্যে @JsonView আমরা ধারাবাহিকভাবে করতে মডেল ক্লাস ক্ষেত্র যা ন্যূনতম মানদণ্ড সন্তুষ্ট (আমরা মানদণ্ড নির্ধারণ করতে আছে) সিদ্ধান্ত নিতে পারেন মত আমরা 10 properties সহযোগে এক কোটি বর্গ থাকতে পারে কিন্তু মাত্র 5 বৈশিষ্ট্য ধারাবাহিকভাবে যা ক্লায়েন্টের জন্য প্রয়োজনীয় হয় হতে পারে কেবল

কেবলমাত্র নিম্নলিখিত ক্লাস তৈরি করে আমাদের দর্শন সংজ্ঞা দিন:

public class Views
{
    static class Android{};
    static class IOS{};
    static class Web{};
}

মতামত সহ টিকাশিত মডেল শ্রেণি:

public class Demo 
{
    public Demo() 
    {
    }

@JsonView(Views.IOS.class)
private String iosField;

@JsonView(Views.Android.class)
private String androidField;

@JsonView(Views.Web.class)
private String webField;

 // getters/setters
...
..
}

এখন আমাদের কেবল কাস্টম জসন রূপান্তরকারীটি বসন্ত থেকে কেবল এইচটিটিপিমেসেজ কনভার্টারের ক্লাসকে বাড়িয়ে লিখে লিখতে হবে:

    public class CustomJacksonConverter implements HttpMessageConverter<Object> 
    {
    public CustomJacksonConverter() 
        {
            super();
        //this.delegate.getObjectMapper().setConfig(this.delegate.getObjectMapper().getSerializationConfig().withView(Views.ClientView.class));
        this.delegate.getObjectMapper().configure(MapperFeature.DEFAULT_VIEW_INCLUSION, true);
        this.delegate.getObjectMapper().setSerializationInclusion(Include.NON_NULL);

    }

    // a real message converter that will respond to methods and do the actual work
    private MappingJackson2HttpMessageConverter delegate = new MappingJackson2HttpMessageConverter();

    @Override
    public boolean canRead(Class<?> clazz, MediaType mediaType) {
        return delegate.canRead(clazz, mediaType);
    }

    @Override
    public boolean canWrite(Class<?> clazz, MediaType mediaType) {
        return delegate.canWrite(clazz, mediaType);
    }

    @Override
    public List<MediaType> getSupportedMediaTypes() {
        return delegate.getSupportedMediaTypes();
    }

    @Override
    public Object read(Class<? extends Object> clazz,
            HttpInputMessage inputMessage) throws IOException,
            HttpMessageNotReadableException {
        return delegate.read(clazz, inputMessage);
    }

    @Override
    public void write(Object obj, MediaType contentType, HttpOutputMessage outputMessage) throws IOException, HttpMessageNotWritableException 
    {
        synchronized(this) 
        {
            String userAgent = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest().getHeader("userAgent");
            if ( userAgent != null ) 
            {
                switch (userAgent) 
                {
                case "IOS" :
                    this.delegate.getObjectMapper().setConfig(this.delegate.getObjectMapper().getSerializationConfig().withView(Views.IOS.class));
                    break;
                case "Android" :
                    this.delegate.getObjectMapper().setConfig(this.delegate.getObjectMapper().getSerializationConfig().withView(Views.Android.class));
                    break;
                case "Web" :
                    this.delegate.getObjectMapper().setConfig(this.delegate.getObjectMapper().getSerializationConfig().withView( Views.Web.class));
                    break;
                default:
                    this.delegate.getObjectMapper().setConfig(this.delegate.getObjectMapper().getSerializationConfig().withView( null ));
                    break;
                }
            }
            else
            {
                // reset to default view
                this.delegate.getObjectMapper().setConfig(this.delegate.getObjectMapper().getSerializationConfig().withView( null ));
            }
            delegate.write(obj, contentType, outputMessage);
        }
    }

}

এখন এই প্রথাটি-সার্লেটলেট.এক্সএমএল-এ রেখে কাস্টম জসন রূপান্তরটি ব্যবহার করার জন্য বসন্তকে বলা দরকার

<mvc:annotation-driven>
        <mvc:message-converters register-defaults="true">
            <bean id="jsonConverter" class="com.mactores.org.CustomJacksonConverter" >
            </bean>
        </mvc:message-converters>
    </mvc:annotation-driven>

এভাবেই আপনি কোন ক্ষেত্রটি সিরিয়ালযুক্ত করতে পারবেন তা স্থির করতে পারবেন।

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