向 Jackson 反序列化器添加自定义参数
Adding custom arguments to Jackson deserializer
我有一个自定义解串器。但我希望能够传递额外的参数。例如
@JsonDeserialize(using=CustomDeserializer.class, customParm=value)
MyObject obj;
如何在注释中传递我的自定义参数?
您不能将自己的参数添加到 @JsonDeserialize
,
因为您无法更改 Jackson 对此注释的实现。
但是,您可以通过稍微不同的方式实现您的目标。
您可以发明自己的注释(我们称之为 @MyAnnotation
)
并将其与 @JsonDeserialize
注释一起用于 属性:
@JsonDeserialize(using = CustomDeserializer.class)
@MyAnnotation(customParm = "value")
private MyObject obj;
注释的实现非常简单。
以下示例注释仅定义了一个 String
参数。
@Target({ ElementType.FIELD })
@Retention(RetentionPolicy.RUNTIME)
public @interface MyAnnotation {
String customParm();
}
然后您可以从内部访问 @MyAnnotation
的参数
你的反序列化器如下。
像往常一样你的解串器需要实现deserialize
方法
您在哪里进行 属性.
的实际反序列化
除此之外你的解串器需要实现
ContextualDeserializer
interface
并实施 createContextual
method。
在这里配置反序列化器(通过从 @MyAnnotation
获取 customParm
)。
Jackson 将在实际反序列化之前调用此方法。
public class CustomDeserializer extends StdDeserializer<MyObject> implements ContextualDeserializer {
private String customParm = null;
public CustomDeserializer() {
super(MyObject.class);
}
public CustomDeserializer(String customParm) {
super(MyObject.class);
this.customParm = customParm;
}
@Override
public JsonDeserializer<?> createContextual(DeserializationContext ctxt, BeanProperty property)
throws JsonMappingException {
MyAnnotation myAnnotation = property.getAnnotation(MyAnnotation.class);
if (myAnnotation != null) {
String customParm = myAnnotation.customParm();
// return a new instance, so that different properties will not share the same deserializer instance
return new CustomDeserializer(customParm);
}
return this;
}
@Override
public MyObject deserialize(JsonParser p, DeserializationContext ctxt) throws IOException, JsonProcessingException {
// do your deserialization (using customParm)
return ...;
}
}
根据之前的解决方案,我创建了我的自定义日期deserializer.And它对我有用。
首先创建您的注释。
@Target({ ElementType.FIELD })
@Retention(RetentionPolicy.RUNTIME)
public @interface CustomDateFormat {
String customDateFormat();
}
其次创建序列化程序class。
public class CustomDateDeserializer extends StdDeserializer<DateTime> implements ContextualDeserializer {
private SimpleDateFormat formatter = new SimpleDateFormat("dd/MM/yyyy");
private String customDateFormat = null;
public CustomDateDeserializer() {
this(null);
}
public CustomDateDeserializer(Class<?> vc) {
super(vc);
}
public CustomDateDeserializer(Class<?> vc, String customDateFormat) {
super(vc);
this.customDateFormat = customDateFormat;
}
@Override
public DateTime deserialize(JsonParser jsonparser, DeserializationContext context) throws IOException {
String date = jsonparser.getText();
try {
if (!Util.nullToBosluk(date).equals(""))
return new DateTime(getDateFormat(this.customDateFormat).parse(date));
} catch (ParseException e) {
throw new RuntimeException(e);
}
return null;
}
@Override
public JsonDeserializer<?> createContextual(DeserializationContext ctxt, BeanProperty property)
throws JsonMappingException {
CustomDateFormat customDateFormatAnn = property.getAnnotation(CustomDateFormat.class);
if (customDateFormatAnn != null) {
String customParam = customDateFormatAnn.customDateFormat();
return new CustomDateDeserializer(this._valueClass, customParam);
}
return this;
}
private DateFormat getDateFormat(String customDateFormat) {
if (StringUtils.isNotBlank(customDateFormat))
return new SimpleDateFormat(customDateFormat);
else
return this.formatter;
}
}
终于在您的代码中使用您的新注释了。
...
@JsonDeserialize(using = CustomDateDeserializer.class)
DateTime invoiceDate;
@JsonDeserialize(using = CustomDateDeserializer.class)
@CustomDateFormat(customDateFormat = "dd/MM/yyyy HH:mm")
DateTime createDate;
...
我有一个自定义解串器。但我希望能够传递额外的参数。例如
@JsonDeserialize(using=CustomDeserializer.class, customParm=value)
MyObject obj;
如何在注释中传递我的自定义参数?
您不能将自己的参数添加到 @JsonDeserialize
,
因为您无法更改 Jackson 对此注释的实现。
但是,您可以通过稍微不同的方式实现您的目标。
您可以发明自己的注释(我们称之为 @MyAnnotation
)
并将其与 @JsonDeserialize
注释一起用于 属性:
@JsonDeserialize(using = CustomDeserializer.class)
@MyAnnotation(customParm = "value")
private MyObject obj;
注释的实现非常简单。
以下示例注释仅定义了一个 String
参数。
@Target({ ElementType.FIELD })
@Retention(RetentionPolicy.RUNTIME)
public @interface MyAnnotation {
String customParm();
}
然后您可以从内部访问 @MyAnnotation
的参数
你的反序列化器如下。
像往常一样你的解串器需要实现
的实际反序列化deserialize
方法 您在哪里进行 属性.除此之外你的解串器需要实现
ContextualDeserializer
interface 并实施createContextual
method。 在这里配置反序列化器(通过从@MyAnnotation
获取customParm
)。 Jackson 将在实际反序列化之前调用此方法。
public class CustomDeserializer extends StdDeserializer<MyObject> implements ContextualDeserializer {
private String customParm = null;
public CustomDeserializer() {
super(MyObject.class);
}
public CustomDeserializer(String customParm) {
super(MyObject.class);
this.customParm = customParm;
}
@Override
public JsonDeserializer<?> createContextual(DeserializationContext ctxt, BeanProperty property)
throws JsonMappingException {
MyAnnotation myAnnotation = property.getAnnotation(MyAnnotation.class);
if (myAnnotation != null) {
String customParm = myAnnotation.customParm();
// return a new instance, so that different properties will not share the same deserializer instance
return new CustomDeserializer(customParm);
}
return this;
}
@Override
public MyObject deserialize(JsonParser p, DeserializationContext ctxt) throws IOException, JsonProcessingException {
// do your deserialization (using customParm)
return ...;
}
}
根据之前的解决方案,我创建了我的自定义日期deserializer.And它对我有用。
首先创建您的注释。
@Target({ ElementType.FIELD })
@Retention(RetentionPolicy.RUNTIME)
public @interface CustomDateFormat {
String customDateFormat();
}
其次创建序列化程序class。
public class CustomDateDeserializer extends StdDeserializer<DateTime> implements ContextualDeserializer {
private SimpleDateFormat formatter = new SimpleDateFormat("dd/MM/yyyy");
private String customDateFormat = null;
public CustomDateDeserializer() {
this(null);
}
public CustomDateDeserializer(Class<?> vc) {
super(vc);
}
public CustomDateDeserializer(Class<?> vc, String customDateFormat) {
super(vc);
this.customDateFormat = customDateFormat;
}
@Override
public DateTime deserialize(JsonParser jsonparser, DeserializationContext context) throws IOException {
String date = jsonparser.getText();
try {
if (!Util.nullToBosluk(date).equals(""))
return new DateTime(getDateFormat(this.customDateFormat).parse(date));
} catch (ParseException e) {
throw new RuntimeException(e);
}
return null;
}
@Override
public JsonDeserializer<?> createContextual(DeserializationContext ctxt, BeanProperty property)
throws JsonMappingException {
CustomDateFormat customDateFormatAnn = property.getAnnotation(CustomDateFormat.class);
if (customDateFormatAnn != null) {
String customParam = customDateFormatAnn.customDateFormat();
return new CustomDateDeserializer(this._valueClass, customParam);
}
return this;
}
private DateFormat getDateFormat(String customDateFormat) {
if (StringUtils.isNotBlank(customDateFormat))
return new SimpleDateFormat(customDateFormat);
else
return this.formatter;
}
}
终于在您的代码中使用您的新注释了。
...
@JsonDeserialize(using = CustomDateDeserializer.class)
DateTime invoiceDate;
@JsonDeserialize(using = CustomDateDeserializer.class)
@CustomDateFormat(customDateFormat = "dd/MM/yyyy HH:mm")
DateTime createDate;
...