【问题标题】:Jackson custom date serializerJackson 自定义日期序列化器
【发布时间】:2015-01-30 14:27:00
【问题描述】:

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

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 设置所需的格式吗? 像这样的:

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

在下面的答案之后:

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

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

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

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

【问题讨论】:

标签: java json serialization jackson


【解决方案1】:

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

这是 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 注释。

这是一个例子:

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

【讨论】:

  • 您好,谢谢!这是一个很好的解决方案。但我使用 @ResponseBody 和代码,在 main bloc 中,对我来说是多余的。我可以用注释序列化一个对象吗?我的意思是:@MyJsonFormat("MM/dd/yyyy") @JsonSerialize(using = MyDateSerializer.class) private Date startDate;就在这种情况下,我得到了异常,因为 MyDateSerializer 等待参数。我试图创建没有参数的构造函数,但在这种情况下,我在序列化方法中得到 NullPointer :)
  • 我已经更新了这个问题(在下面的答案之后:)。你怎么看?
  • @AlexSmith 很难说没有看到异常堆栈跟踪。我建议在调试器下运行它来检查那里有什么问题。
猜你喜欢
  • 2023-03-22
  • 2016-01-11
  • 2016-02-13
  • 2011-04-12
  • 2016-02-18
  • 2018-05-06
  • 2016-01-29
  • 1970-01-01
  • 2019-08-10
相关资源
最近更新 更多