<bdo id='J4U9G'></bdo><ul id='J4U9G'></ul>
    1. <small id='J4U9G'></small><noframes id='J4U9G'>

      <tfoot id='J4U9G'></tfoot>

      <i id='J4U9G'><tr id='J4U9G'><dt id='J4U9G'><q id='J4U9G'><span id='J4U9G'><b id='J4U9G'><form id='J4U9G'><ins id='J4U9G'></ins><ul id='J4U9G'></ul><sub id='J4U9G'></sub></form><legend id='J4U9G'></legend><bdo id='J4U9G'><pre id='J4U9G'><center id='J4U9G'></center></pre></bdo></b><th id='J4U9G'></th></span></q></dt></tr></i><div id='J4U9G'><tfoot id='J4U9G'></tfoot><dl id='J4U9G'><fieldset id='J4U9G'></fieldset></dl></div>

      1. <legend id='J4U9G'><style id='J4U9G'><dir id='J4U9G'><q id='J4U9G'></q></dir></style></legend>
      2. 使用@JsonFormat的一个坑及解决

        时间:2023-12-10

          <i id='ojLE8'><tr id='ojLE8'><dt id='ojLE8'><q id='ojLE8'><span id='ojLE8'><b id='ojLE8'><form id='ojLE8'><ins id='ojLE8'></ins><ul id='ojLE8'></ul><sub id='ojLE8'></sub></form><legend id='ojLE8'></legend><bdo id='ojLE8'><pre id='ojLE8'><center id='ojLE8'></center></pre></bdo></b><th id='ojLE8'></th></span></q></dt></tr></i><div id='ojLE8'><tfoot id='ojLE8'></tfoot><dl id='ojLE8'><fieldset id='ojLE8'></fieldset></dl></div>
          <tfoot id='ojLE8'></tfoot>

              • <bdo id='ojLE8'></bdo><ul id='ojLE8'></ul>

                    <tbody id='ojLE8'></tbody>
                  <legend id='ojLE8'><style id='ojLE8'><dir id='ojLE8'><q id='ojLE8'></q></dir></style></legend>

                  <small id='ojLE8'></small><noframes id='ojLE8'>

                  使用@JsonFormat注解可以自定义将Java对象转换为JSON字符串时的日期格式,但是在使用过程中也存在一个坑点。具体攻略如下:

                  1.问题描述

                  我们在使用@JsonFormat注解时,想要将日期格式化为类似"yyyy-MM-dd HH:mm:ss.SSS"的字符串格式,于是我们在实体类上添加该注解:

                  public class User {
                      private Long id;
                      private String name;
                      @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss.SSS", timezone = "Asia/Shanghai")
                      private Date createTime;
                      //getters/setters...
                  }
                  

                  在将该实体类转换为JSON字符串时,我们期望得到的日期格式应该是"2021-08-31 15:30:40.123"这样的结果。但是实际上转换后却是"2021-09-01T07:30:40.123+0000"这样的结果,时间格式和时区都并不是我们设置的内容。

                  2.问题分析

                  JsonFormat注解中的"timezone"属性,其实是将java中的Date对象按照指定的timezone转为标准时间字符串,然后再转换成JSON字符串。因此,问题就在于@JsonFormat注解没有将我们设置的时间格式直接应用到Date对象上,因为各个时区的时间格式可能是不同的。

                  3.解决方案

                  要解决这个问题,我们需要在转换JSON字符串时,指定jackson的序列化配置。具体来说,就是通过自定义ObjectMapper,设置其默认的输出时间格式和时区。以下是两种实现方式:

                  方式一:编写ObjectMapperProvider

                  编写ObjectMapperProvider,设置默认的输出时间格式和时区:

                  import com.fasterxml.jackson.annotation.JsonInclude;
                  import com.fasterxml.jackson.databind.ObjectMapper;
                  import com.fasterxml.jackson.databind.SerializationFeature;
                  import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule;
                  import org.slf4j.Logger;
                  import org.slf4j.LoggerFactory;
                  import org.springframework.http.converter.json.Jackson2ObjectMapperBuilder;
                  import org.springframework.http.converter.json.Jackson2ObjectMapperFactoryBean;
                  import org.springframework.http.converter.json.MappingJackson2HttpMessageConverter;
                  
                  import java.text.DateFormat;
                  import java.text.SimpleDateFormat;
                  import java.util.TimeZone;
                  
                  public class CustomObjectMapperProvider {
                  
                      private static final Logger log = LoggerFactory.getLogger(CustomObjectMapperProvider.class);
                  
                      public ObjectMapper createObjectMapper() {
                          DateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS");
                          dateFormat.setTimeZone(TimeZone.getTimeZone("Asia/Shanghai"));
                  
                          ObjectMapper objectMapper = new Jackson2ObjectMapperBuilder().build();
                  
                          objectMapper.setSerializationInclusion(JsonInclude.Include.NON_NULL);
                          objectMapper.disable(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS);
                          objectMapper.setTimeZone(TimeZone.getTimeZone("Asia/Shanghai"));
                          objectMapper.setDateFormat(dateFormat);
                  
                          // Register JavaTimeModule
                          objectMapper.registerModule(new JavaTimeModule());
                          // Fix Jackson2DateFormat issue (https://github.com/FasterXML/jackson-databind/issues/1072)
                          objectMapper.findAndRegisterModules();
                  
                          return objectMapper;
                      }
                  }
                  

                  在上面的例子中,我们使用了SimpleDateFormat指定了默认输出的时间格式,同时也设置了时区。我们通过Jackson2ObjectMapperBuilder来构建ObjectMapper对象,然后通过ObjectMapper的方法设置它的序列化配置。最后,在ObjectMapper中注册JavaTimeModule(解决LocalDateTime转换的问题)。

                  方式二:编写自定义序列化器

                  除了通过ObjectMapper的方式来解决这个问题之外,我们还可以编写自定义序列化器,将Java中的Data对象按照我们预期的方式进行序列化。以下是示例代码:

                  import com.fasterxml.jackson.core.JsonGenerator;
                  import com.fasterxml.jackson.databind.JsonSerializer;
                  import com.fasterxml.jackson.databind.SerializerProvider;
                  import org.springframework.boot.jackson.JsonComponent;
                  
                  import java.io.IOException;
                  import java.text.SimpleDateFormat;
                  import java.util.Date;
                  import java.util.TimeZone;
                  
                  @JsonComponent
                  public class JsonDateSerializer extends JsonSerializer<Date> {
                  
                      private static final SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS");
                      static {
                          dateFormat.setTimeZone(TimeZone.getTimeZone("Asia/Shanghai"));
                      }
                  
                      @Override
                      public void serialize(Date value, JsonGenerator gen, SerializerProvider serializers) throws IOException {
                          gen.writeString(dateFormat.format(value));
                      }
                  }
                  

                  在上面的代码中,我们使用@JsonComponent注解将自定义的序列化器注册到Spring Boot框架中。同时,我们也在该序列化器中使用了SimpleDateFormat指定了默认输出的时间格式,同时也设置了时区。注意,这个方法里必须手动写代码将日期转为字符串进行输出。

                  4.总结

                  当使用@JsonFormat时,无法直接实现对Java对象的日期格式化。应该使用自定义ObjectMapper或者自定义序列化器的方式,对日期格式和时区进行配置,才能正确地将Java对象转换为JSON字符串。

                  上一篇:关于@JSONField和@JsonFormat的使用区别说明 下一篇:java中this的n种使用方法

                  相关文章

                1. <i id='3xSV1'><tr id='3xSV1'><dt id='3xSV1'><q id='3xSV1'><span id='3xSV1'><b id='3xSV1'><form id='3xSV1'><ins id='3xSV1'></ins><ul id='3xSV1'></ul><sub id='3xSV1'></sub></form><legend id='3xSV1'></legend><bdo id='3xSV1'><pre id='3xSV1'><center id='3xSV1'></center></pre></bdo></b><th id='3xSV1'></th></span></q></dt></tr></i><div id='3xSV1'><tfoot id='3xSV1'></tfoot><dl id='3xSV1'><fieldset id='3xSV1'></fieldset></dl></div>

                    • <bdo id='3xSV1'></bdo><ul id='3xSV1'></ul>

                    1. <legend id='3xSV1'><style id='3xSV1'><dir id='3xSV1'><q id='3xSV1'></q></dir></style></legend>

                      <small id='3xSV1'></small><noframes id='3xSV1'>

                    2. <tfoot id='3xSV1'></tfoot>