处理注释混合的杰克逊代码是否可以被第三方重用以混合非杰克逊注释?
处理mixins的核心杰克逊课程是什么?
答案 0 :(得分:1)
您必须实施界面com.fasterxml.jackson.databind.ser.ContextualSerializer
和/或com.fasterxml.jackson.databind.deser.ContextualDeserializer
。杰克逊序列化并反序列化JSON。如果这不是您的意图,您将获得一些开销,而另一种方法可能会更好(例如,AspectJ的解决方案)。
如果您对Jackson的实施感兴趣以及如何使用(de)序列化器:
This project包含Jackson数据处理器的通用数据绑定功能和树模型。它建立在核心流解析器/生成器包之上,并使用Jackson Annotations进行配置。
分析的良好切入点:ObjectMapper
此代码演示了如何使用自定义注释(在mixin中使用)以及如何实现合适的(de)序列化器:
public class MyBean {
private String value;
public String getValue() {
return value;
}
public void setValue(String value) {
this.value = value;
}
}
/////
import com.fasterxml.jackson.annotation.JacksonAnnotation;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
@Target({ElementType.FIELD, ElementType.METHOD, ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@JacksonAnnotation // important so that it will get included!
public @interface MyAnnotation {
public String value();
}
/////
public abstract class MyMixin {
@MyAnnotation("Hello")
public abstract String getValue();
}
/////
import com.fasterxml.jackson.core.JsonParser;
import com.fasterxml.jackson.databind.*;
import com.fasterxml.jackson.databind.deser.ContextualDeserializer;
import com.fasterxml.jackson.databind.deser.std.StringDeserializer;
import java.io.IOException;
public class MyDeserializer extends JsonDeserializer<String> implements ContextualDeserializer {
private String annoValue;
public MyDeserializer(){}
public MyDeserializer(MyAnnotation ann) {
annoValue = ann.value();
}
@Override
public String deserialize(JsonParser p, DeserializationContext ctxt) throws IOException {
String serializedValue = p.getText();
return serializedValue.substring(annoValue.length() + 1, serializedValue.length() - 1);
}
public JsonDeserializer<?> createContextual(DeserializationContext ctxt, BeanProperty prop) throws JsonMappingException {
MyAnnotation ann = prop.getAnnotation(MyAnnotation.class);
if (ann == null) {
ann = prop.getContextAnnotation(MyAnnotation.class);
}
if (ann == null) {
return new StringDeserializer();
}
return new MyDeserializer(ann);
}
}
/////
import com.fasterxml.jackson.core.JsonGenerator;
import com.fasterxml.jackson.databind.*;
import com.fasterxml.jackson.databind.ser.ContextualSerializer;
import com.fasterxml.jackson.databind.ser.std.StringSerializer;
import java.io.IOException;
public class MySerializer extends JsonSerializer<String> implements ContextualSerializer {
private String annoValue;
public MySerializer() {}
public MySerializer(MyAnnotation ann) {
annoValue = ann.value();
}
@Override
public void serialize(String toSerialize, JsonGenerator gen, SerializerProvider prov) throws IOException {
gen.writeString(annoValue + " " + toSerialize + "!");
}
public JsonSerializer createContextual(SerializerProvider prov, BeanProperty prop) throws JsonMappingException {
MyAnnotation ann = prop.getAnnotation(MyAnnotation.class);
if (ann == null) {
ann = prop.getContextAnnotation(MyAnnotation.class);
}
if (ann == null) {
return new StringSerializer();
}
return new MySerializer(ann);
}
}
/////
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.module.SimpleModule;
import java.io.IOException;
public class Main {
public static void main(String[] args) throws IOException {
ObjectMapper mapper = new ObjectMapper();
SimpleModule module = new SimpleModule();
module.addSerializer(String.class, new MySerializer());
module.addDeserializer(String.class, new MyDeserializer());
mapper.registerModule(module);
mapper.addMixIn(MyBean.class, MyMixin.class);
MyBean bean = new MyBean();
bean.setValue("World");
String jsonInString = mapper.writeValueAsString(bean);
System.out.println(jsonInString);
MyBean deserialized = mapper.readValue(jsonInString, MyBean.class);
System.out.println(deserialized.getValue());
}
}