Jackson 自定义日期序列化器 [英] Jackson custom date serializer

查看:63
本文介绍了Jackson 自定义日期序列化器的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我需要为班级的日期序列化设置格式.我有没有@JsonFormat 的 Jackson 版本.这就是我编写自定义类的原因:

I need to set format for class' date serialization. I have the version of Jackson, which doesn't have @JsonFormat. That's Why I wrote custom class:

public class CDJsonDateSerializer extends JsonSerializer<Date>{

@Override
public void serialize(Date date, JsonGenerator jsonGenerator, SerializerProvider provider) throws IOException {
    SimpleDateFormat dateFormat = new SimpleDateFormat("MM/dd/yyyy");
    String dateString = dateFormat.format(date);
    jsonGenerator.writeString(dateString);
}

}

并使用它:

@JsonSerialize(using = CDJsonDateSerializer.class)
private Date startDate;

但是,我有另一个具有不同日期格式的字段,我不想为序列化创建另一个类.我可以将所有需要的格式(如常量)添加到 CDJsonDateSerializer 类并使用注释 @JsonSerialize 设置所需的格式吗?像这样:

But, I have another fields which have different date's formats and I don't want to create another classes for serialization. Can I add all needed formats like constants to CDJsonDateSerializer class and set needed format with annotation @JsonSerialize ? Something like this:

@JsonSerialize(using = CDJsonDateSerializer.class, CDJsonDateSerializer.FIRST_FORMAT).

在回答以下之后:

经过一些更正后它可以工作.我改变了在 createContextual 方法中获取注释的方式:

It works after some corrections. I've changed the way of getting annotation in createContextual method:

@Override
public JsonSerializer createContextual(SerializationConfig serializationConfig, BeanProperty beanProperty) {
    return new CustomDateSerializer(beanProperty.getAnnotation(JsonDateFormat.class).value());
}

并且我已将 @JacksonAnnotation 添加到我创建的新注释 JsonDateFormat 中:

And I've added @JacksonAnnotation to my created new annotation JsonDateFormat:

@Retention(RetentionPolicy.RUNTIME)
@JacksonAnnotation
public @interface JsonDateFormat {
   String value();
}

推荐答案

如果你不能使用 @JsonFormat从 Jackson 2 开始,我建议您引入自己的自定义注释,其中将包含格式字段.然后,您的 serailizer 应实现 ContextualSerializer 接口以访问注释值.

If you cannot use @JsonFormat from Jackson 2, I'd recommend you to introduce your own custom annotation which will contain the format field. Your serailizer should then implement the ContextualSerializer interface to get access to the annotation value.

以下是 Jackson 1.9.X 的示例:

Here is an example for Jackson 1.9.X:

public class JacksonDateFormat {
    @Retention(RetentionPolicy.RUNTIME)
    public static @interface MyJsonFormat {
        String value();
    }

    public static class Bean {
        @MyJsonFormat("dd.MM.yyyy") @JsonSerialize(using = MyDateSerializer.class)
        public final Date date1;

        @MyJsonFormat("yyyy-MM-dd") @JsonSerialize(using = MyDateSerializer.class)
        public final Date date2;

        public Bean(final Date date1, final Date date2) {
            this.date1 = date1;
            this.date2 = date2;
        }
    }

    public static class MyDateSerializer extends JsonSerializer<Date>
            implements ContextualSerializer {
        private final String format;

        private MyDateSerializer(final String format) {this.format = format;}

        public MyDateSerializer() {this.format = null;}

        @Override
        public void serialize(
                final Date value, final JsonGenerator jgen, final SerializerProvider provider)
                throws IOException {
            jgen.writeString(new SimpleDateFormat(format).format(value));
        }

        @Override
        public JsonSerializer createContextual(
                final SerializationConfig serializationConfig, final BeanProperty beanProperty)
                throws JsonMappingException {
            final AnnotatedElement annotated = beanProperty.getMember().getAnnotated();
            return new MyDateSerializer(annotated.getAnnotation(MyJsonFormat.class).value());
        }
    }

    public static void main(String[] args) throws IOException {
        final ObjectMapper mapper = new ObjectMapper();
        final Bean value = new Bean(new Date(), new Date());
        System.out.println(mapper
                        .writerWithDefaultPrettyPrinter()
                        .writeValueAsString(value));
    }
}

输出:

{
  "date1" : "02.12.2014",
  "date2" : "2014-12-02"
}

如果您有权访问 ObjectMapper,您可以为所有 Date 类型注册您的自定义序列化程序,因此您希望不再需要放置 @JsonSerialize注释.

If you have access to the ObjectMapper you can register your custom serializer for all the Date types, so you want longer need to put @JsonSerialize annotation.

这是一个例子:

final ObjectMapper mapper = new ObjectMapper();
final SimpleModule module = new SimpleModule("", Version.unknownVersion());
module.addSerializer(Date.class, new MyDateSerializer(null));
mapper.registerModule(module);

这篇关于Jackson 自定义日期序列化器的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆