Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
1.4k views
in Technique[技术] by (71.8m points)

java - Different JSON configuration in a Spring application for REST and Ajax serialization

In a Spring application I have added a custom JSON serializer which is applied to a field with thte tag:

@JsonSerialize(using=MySerializer.class)

And the MySerializer serializer (whcihc extends from JsonSerializer) has a method which looks like:

@Override
public void serialize(String value, JsonGenerator jsonGenerator, SerializerProvider serializerProvider) throws IOException, JsonProcessingException
{ 
    //some logic
}

It works and execute the logic when the application generates json in the methods annotated with @ResponseBody but it also executes the same logic when the application uses a webservice with JSON. I'd like to set up different configurations for the RestTemplate serialization and for @ResponseBody, or at least, being able to differenciate in the serializate method whether we are in a @ResponseBody case or in a RestTemplate one.

Any idea on how to do this?

Thanks.

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

You should use Mix-in Annotations feature. For example, your POJO classes could look like that:

class Root {

    private Data data;

    // getters/setters
}

class Data {

    private String name;

    // getters/setters
}

Now, you have to create MixIn interface:

interface RootMixIn {

    @JsonSerialize(using = DataSerializer.class)
    Data getData();
}

Imagine, that custom serializer looks like this:

class DataSerializer extends JsonSerializer<Data> {

    @Override
    public void serialize(Data data, JsonGenerator generator, SerializerProvider provider) throws IOException, JsonProcessingException {
        generator.writeStartObject();
        generator.writeFieldName("name_property");
        generator.writeString(data.getName() + " XXX");
        generator.writeEndObject();
    }
}

Finally, you have to create two ObjectMapper's. Simple usage:

Data data = new Data();
data.setName("Tom");

Root root = new Root();
root.setData(data);

ObjectMapper mapperWithMixIn = new ObjectMapper();
mapperWithMixIn.addMixInAnnotations(Root.class, RootMixIn.class);

ObjectMapper mapperDefault = new ObjectMapper();

System.out.println("With MIX-IN");
System.out.println(mapperWithMixIn.writeValueAsString(root));

System.out.println("Default");
System.out.println(mapperDefault.writeValueAsString(root));

Above script prints:

With MIX-IN
{"data":{"name_property":"Tom XXX"}}
Default
{"data":{"name":"Tom"}}

As you can see, ObjectMapper with MixIn you can use in request handlers, and default ObjectMapper you can use in RestTemplate.

Update 1

Spring creates default ObjectMapper bean and uses it to serialize and deserialize request's data. You have to find and override this default bean. How to do it? Please, see below links:

This overridden bean should look like mapperWithMixIn in my above example.

Secondly, you have to create new ObjectMapper bean and inject this bean to all RestTemplate-s and use this bean in these classes as a serializer/deserializer.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...