【问题标题】:Format with Jackson格式与杰克逊
【发布时间】:2021-03-02 03:31:00
【问题描述】:

我有一个 OffsetDateTime。 在 json 中使用 Jackson 我看到了这个值:

2021-03-01T22:21:02.8624372-05:00

在我使用的领域

@JsonFormat(pattern="yyyy-MM-dd'T'HH:mm:ssZ")

显示此值

2021-03-01T22:21:02-0500

有什么想法

2021-03-01T22:21:02-05:00

【问题讨论】:

  • 我很困惑。第一个 sn-p 是杰克逊消费之前的 JSON?那么第三个 sn-p 是如何打印的,如果你对相应的解析对象执行toString
  • 第一个sn-p是jackson生成的值,当我输入JsonFormat时,我得到的是jackson生成的第三个sn-p
  • 试试这个:@JsonFormat(pattern="yyyy-MM-dd'T'HH:mm:ssxxxx"),让我们知道它是否有效。
  • 得到相同的结果

标签: java json jackson datetimeoffset


【解决方案1】:

Instant 也有类似的问题。在那里,我覆盖了JavaTimeModuleInstant 序列化程序并使用了自定义DateTimeFormatter,如下所示:

ObjectMapper objectMapper = new ObjectMapper();
        
DateTimeFormatter instantFormatter = new DateTimeFormatterBuilder()
    .appendInstant(0)
    .toFormatter();
        
JavaTimeModule jtm = new JavaTimeModule();
jtm.addSerializer(Instant.class, new JsonSerializer<Instant>() {
    @Override
    public void serialize(Instant value, JsonGenerator gen, SerializerProvider serializers) throws IOException, JsonProcessingException {
        gen.writeString(instantFormatter.format(value));
    }
});

objectMapper.registerModule(jtm);

但您也应该能够在该特定字段上使用@JsonSerialize 而不是@JsonFormat

@JsonSerialize(using = MyCustomSerializer.class)
OffsetDateTime problematicField;

DateTimeFormatterBuilder 让您轻松自定义格式

【讨论】:

    【解决方案2】:

    假设您已经在使用JavaTimeModule(将WRITE_DATES_AS_TIMESTAMPS 用作在您的第一个sn-p 中产生输出的false),您只需在@JsonFormat 中提供适当的日期模式,即.

    @JsonFormat(pattern = "yyyy-MM-dd'T'HH:mm:ssZZZZZ")
    

    pattern 在哪里

    数据类型特定的附加配置,可用于进一步细化格式方面。例如,这可以确定用于java.util.Date 序列化的低级格式字符串;但是,具体使用由具体的JsonSerializer决定。

    这里的“特定日期类型”是JsonSerializer 的序列化程序。由于您使用的是JavaTimeModule(假设!!!),那就是OffsetDateTimeSerializer@JsonFormat pattern 被解释为 DateTimeFormatter 模式,它声明

    偏移 Z:这会根据模式字母的数量来格式化偏移。一个、两个或三个字母输出小时和分钟,不带冒号,例如'+0130'。当偏移量为零时,输出将为“+0000”。四个字母输出本地化偏移的完整形式,相当于四个字母的Offset-O。如果偏移量为零,则输出将是相应的本地化偏移量文本。 五个字母输出小时、分钟,如果非零则可选秒,带有冒号。如果偏移量为零,则输出“Z”。六个或更多字母抛出IllegalArgumentException

    【讨论】:

      【解决方案3】:

      有很多方法可以做到,下面的代码显示了简单的两种方法:

      import java.time.OffsetDateTime;
      import java.time.format.DateTimeFormatter;
      import java.util.Date;
      
      import com.fasterxml.jackson.core.JsonProcessingException;
      import com.fasterxml.jackson.databind.ObjectMapper;
      import com.fasterxml.jackson.databind.annotation.JsonSerialize;
      
      public class JsonDateFormat {
      
          /*
           * Approach I
           */
          @SuppressWarnings("static-method")
          public String getCurrentDateTime() {
              return DateTimeFormatter.ISO_OFFSET_DATE_TIME.format(OffsetDateTime.now());
          }
      
          /*
           * Approach II
           */
          @SuppressWarnings("static-method")
          @JsonSerialize(using = CustomDateTimeFormatter.class)
          public Date getCustomCurrentDateTime() {
              return new Date();
          }
      
          public static void main(final String[] args) throws JsonProcessingException {
              final JsonDateFormat jsonDateFormat = new JsonDateFormat();
              final String result = new ObjectMapper().writeValueAsString(jsonDateFormat);
              System.out.println(result);
          }
      
      }
      

      下面是自定义字段序列化器。

      import java.io.IOException;
      import java.time.OffsetDateTime;
      import java.time.ZoneId;
      import java.time.format.DateTimeFormatter;
      import java.util.Date;
      
      import com.fasterxml.jackson.core.JsonGenerator;
      import com.fasterxml.jackson.databind.SerializerProvider;
      import com.fasterxml.jackson.databind.ser.std.StdSerializer;
      
      public class CustomDateTimeFormatter extends StdSerializer<Date> {
      
          private static final long serialVersionUID = 1L;
      
          public CustomDateTimeFormatter() {
              this(null);
          }
      
          public CustomDateTimeFormatter(final Class<Date> t) {
              super(t);
          }
      
          @Override
          public void serialize(final Date date, final JsonGenerator jgen, final SerializerProvider provider) throws IOException {
              final String dateTime = DateTimeFormatter.ISO_OFFSET_DATE_TIME.format(OffsetDateTime.ofInstant(date.toInstant(), ZoneId.systemDefault()));
              jgen.writeObject(dateTime);
          }
      
      }
      

      最后,您还可以使用自定义 DateTimeFormatter。见参考DateTimeFormatter doesn't parse custom date format

      【讨论】:

        猜你喜欢
        • 2014-07-31
        • 1970-01-01
        • 2015-05-02
        • 1970-01-01
        • 2011-08-25
        • 1970-01-01
        • 1970-01-01
        • 2014-08-06
        相关资源
        最近更新 更多