Java Jackson 自定义日期序列化器

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/27247767/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-11 04:02:47  来源:igfitidea点击:

Hymanson custom date serializer

javajsonserializationHymanson

提问by AlexSmith

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

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

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);
}

}

}

And used it:

并使用它:

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

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:

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

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

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

AFTER THE ANSWER BELOW:

在下面的答案之后:

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

它在一些更正后起作用。我改变了在createContextual方法中获取注释的方式:

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

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

我已经将@HymansonAnnotation添加到我创建的新注释 JsonDateFormat 中:

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

采纳答案by Alexey Gavrilov

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

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

Here is an example for Hymanson 1.9.X:

以下是 Hymanson 1.9.X 的示例:

public class HymansonDateFormat {
    @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));
    }
}

Output:

输出:

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

If you have access to the ObjectMapperyou can register your custom serializer for all the Datetypes, so you want longer need to put @JsonSerializeannotation.

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

Here is an example:

下面是一个例子:

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