【发布时间】:2021-08-12 07:18:35
【问题描述】:
我有一个自定义反序列化器。但我希望能够传递额外的参数。例如
@JsonDeserialize(using=CustomDeserializer.class, customParm=value)
MyObject obj;
如何在注解上传入我的自定义参数?
【问题讨论】:
标签: java json jackson deserialization
我有一个自定义反序列化器。但我希望能够传递额外的参数。例如
@JsonDeserialize(using=CustomDeserializer.class, customParm=value)
MyObject obj;
如何在注解上传入我的自定义参数?
【问题讨论】:
标签: java json jackson deserialization
根据以前的解决方案,我创建了我的自定义日期反序列化器。它对我有用。
首先创建您的注释。
@Target({ ElementType.FIELD })
@Retention(RetentionPolicy.RUNTIME)
public @interface CustomDateFormat {
String customDateFormat();
}
第二次创建您的序列化程序类。
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,
因为你不能改变 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 ...;
}
}
【讨论】: