Three spring boot global time formatting methods, do not write duplicate code

Time:2020-9-14

This article is included in personal blog: www.chengxy-nds.top Technical data sharing and progress

Time formatting is used very often in projects when ourAPIThe interface returns the result, and one of thedateField properties are specially formatted, usually usedSimpleDateFormatTool handling.

SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd");
Date stationTime = dateFormat.parse(dateFormat.format(PayEndTime()));

But once there are more places to deal with, not onlyCVFrequent operations also produce a lot of redundant and bloated code. At this time, if the time format can be uniformly configured, more time can be saved to focus on business development.

Maybe many people think that unified format time is very simple. You can configure it like this below, but in fact, this method is only rightdateType is in effect.

spring.jackson.date-format=yyyy-MM-dd HH:mm:ss
spring.jackson.time-zone=GMT+8

And the time and date used in many projectsAPIIt’s chaotic,java.util.Datejava.util.Calendarandjava.time LocalDateTimeTherefore, the global time format must be compatible with both the old and the newAPI


Look at the format of the time field returned by the interface before configuring the global time format.

@Data
public class OrderDTO {

    private LocalDateTime createTime;

    private Date updateTime;
}

Obviously does not meet the display requirements on the page(I can only say that the code of sleeping clothes is much easier than persuading people~

Three spring boot global time formatting methods, do not write duplicate code

1、 @ jsonformat annotation

@JsonFormatStrictly speaking, annotation method can not be called global time format, but should be called partial format, because@JsonFormatThe annotation needs to be used in the time field of the entity class, and only when the corresponding entity class is used can the corresponding field be formatted.

@Data
public class OrderDTO {

    @JsonFormat(locale = "zh", timezone = "GMT+8", pattern = "yyyy-MM-dd")
    private LocalDateTime createTime;

    @JsonFormat(locale = "zh", timezone = "GMT+8", pattern = "yyyy-MM-dd HH:mm:ss")
    private Date updateTime;
}

Field plus@JsonFormatAfter the note,LocalDateTimeandDateTime format succeeded.

Three spring boot global time formatting methods, do not write duplicate code

2、 @ jsoncomponent annotation(recommend

This is a way that I personally recommend. I’ll see how to use it@JsonFormatAnnotations can’t fully format the global time, so let’s use@JsonComponentThe annotation defines a global format class, and sets theDateandLocalDateType is formatted.


@JsonComponent
public class DateFormatConfig {

    @Value("${spring.jackson.date-format:yyyy-MM-dd HH:mm:ss}")
    private String pattern;

    * *
    @Bean
    public Jackson2ObjectMapperBuilderCustomizer jackson2ObjectMapperBuilder() {

        return builder -> {
            TimeZone tz = TimeZone.getTimeZone("UTC");
            DateFormat df = new SimpleDateFormat(pattern);
            df.setTimeZone(tz);
            builder.failOnEmptyBeans(false)
                    .failOnUnknownProperties(false)
                    .featuresToDisable(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS)
                    .dateFormat(df);
        };
    }

    * *
    @Bean
    public LocalDateTimeSerializer localDateTimeDeserializer() {
        return new LocalDateTimeSerializer(DateTimeFormatter.ofPattern(pattern));
    }

    @Bean
    public Jackson2ObjectMapperBuilderCustomizer jackson2ObjectMapperBuilderCustomizer() {
        return builder -> builder.serializerByType(LocalDateTime.class, localDateTimeDeserializer());
    }
}

noticeDateandLocalDateThe two time types are formatted successfully, which is effective.

Three spring boot global time formatting methods, do not write duplicate code

But there is another problem. In actual development, if I have a field that I don’t want to use the global format to set the time style,What do you want to do with custom formats?

Then you need to@JsonFormatAnnotations are used together.

@Data
public class OrderDTO {

    @JsonFormat(locale = "zh", timezone = "GMT+8", pattern = "yyyy-MM-dd")
    private LocalDateTime createTime;

    @JsonFormat(locale = "zh", timezone = "GMT+8", pattern = "yyyy-MM-dd")
    private Date updateTime;
}

We can see from the results@JsonFormatAnnotations have a higher priority and will be@JsonFormatThe time format of notes is the main.

Three spring boot global time formatting methods, do not write duplicate code

3、 @ configuration comment

This global configuration is implemented in the same way as above.

be careful: after using this configuration, the fields are configured manually@JsonFormatThe note will no longer be valid.


@Configuration
public class DateFormatConfig2 {

    @Value("${spring.jackson.date-format:yyyy-MM-dd HH:mm:ss}")
    private String pattern;

    public static DateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");

    @Bean
    @Primary
    public ObjectMapper serializingObjectMapper() {
        ObjectMapper objectMapper = new ObjectMapper();
        JavaTimeModule javaTimeModule = new JavaTimeModule();
        javaTimeModule.addSerializer(LocalDateTime.class, new LocalDateTimeSerializer());
        javaTimeModule.addDeserializer(LocalDateTime.class, new LocalDateTimeDeserializer());
        objectMapper.registerModule(javaTimeModule);
        return objectMapper;
    }

    * *
    @Component
    public class DateSerializer extends JsonSerializer<Date> {
        @Override
        public void serialize(Date date, JsonGenerator gen, SerializerProvider provider) throws IOException {
            String formattedDate = dateFormat.format(date);
            gen.writeString(formattedDate);
        }
    }

    * *
    @Component
    public class DateDeserializer extends JsonDeserializer<Date> {

        @Override
        public Date deserialize(JsonParser jsonParser, DeserializationContext deserializationContext) throws IOException {
            try {
                return dateFormat.parse(jsonParser.getValueAsString());
            } catch (ParseException e) {
                throw new RuntimeException("Could not parse date", e);
            }
        }
    }

    * *
    public class LocalDateTimeSerializer extends JsonSerializer<LocalDateTime> {
        @Override
        public void serialize(LocalDateTime value, JsonGenerator gen, SerializerProvider serializers) throws IOException {
            gen.writeString(value.format(DateTimeFormatter.ofPattern(pattern)));
        }
    }

    * *
    public class LocalDateTimeDeserializer extends JsonDeserializer<LocalDateTime> {
        @Override
        public LocalDateTime deserialize(JsonParser p, DeserializationContext deserializationContext) throws IOException {
            return LocalDateTime.parse(p.getValueAsString(), DateTimeFormatter.ofPattern(pattern));
        }
    }
}

Three spring boot global time formatting methods, do not write duplicate code

summary

Share a simple but practical oneSpringbootAt least one of the skills that programmers can use to develop code is a skill to accomplish the task.

If it works for you, welcomeWatchinggive the thumbs-upforwardYour recognition is my biggest motivation.

Original is not easy, burning hair output content, if there is a loss of harvest, like to encourage it!

Hundreds of technical e-books have been sorted out and sent to our friends. Attention to public name reply【666】Collect it by yourself. We have set up a technology exchange group with some partners to discuss technology and share technical information, aiming to learn and progress together. If you are interested, please join us!