Take over the project left by my old brother, there is a big hole! Processing global date formatting with springboot

Keywords: Programming Java Spring Attribute SpringBoot

Recently, several colleagues of the Department have been wronged and left one after another. They are reluctant to leave when they have been working together for three years. After all the formalities have been properly handled, they are sent out of the company after greetings. Several elder brothers laugh at me when they leave. I immediately feel a bad premonition. This is definitely not so simple.

After I took over the projects of these big guys, I realized my premonition. At the moment, I regret a little. Why didn't I beat them when I saw them off! Ha ha ha ha~

The impulse of beating people became more and more intense when I started to optimize the projects of several elder brothers.

Every month, the technology department organizes code walkthroughs and optimizations. It used to review and optimize its own projects, but now the projects of several elder brothers who quit their jobs fall on my head.

The most painful thing for programmers is to take over other people's projects and make optimization and transformation, because this is no simpler than refactoring a project. However, the military order in front, there is no way to be hard on the scalp!

There's a hole

The first optimization point makes me a little bit broken. These big guys have strong skills and abilities, which have always been my model. But almost all date formats in the project are implemented with SimpleDateFormat, like the following code. emm ~, how can wounded men do anything? Hahaha~

SvcOrderDailyStatisticsPo orderDailyStatisticsPo = new SvcOrderDailyStatisticsPo();
SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd");
Date stationTime = dateFormat.parse(dateFormat.format(svcWorkOrderPo.getPayEndTime()));
orderDailyStatisticsPo.setStatisticalDate(stationTime);

Moreover, the time and date API s in the project are also confused. Considering that java.util.Date and java.util.Calendar do not support time zone, and are non thread safe, the calculation of date is relatively cumbersome, and the technical department unanimously requires java.time LocalDateTime after JDK1.8. But many people are still using Java. Util. Date and Java. Util. Calendar to process dates.

Optimization plan

Time format is very frequently used. How to make time format simple without making wheels repeatedly? Then it should be abstracted and treated as a global date format. Next, several optimization schemes are briefly introduced in combination with practice.

Test address: http://127.0.0.1:8080/timeTest

@GetMapping("/timeTest")
    public OrderInfo timeTest() {
        OrderInfo order = new OrderInfo();
        order.setCreateTime(LocalDateTime.now());
        order.setUpdateTime(new Date());
        return order;
    }

1. Annotation of @ JsonFormat

Using @ JsonFormat annotation to format time is a basic operation. Most developers use this method, which is simple and convenient.

/**
 * @Author: xiaofu
 * @Description:
 */
public class OrderInfo {
​
    @JsonFormat(locale = "zh", timezone = "GMT+8", pattern = "yyyy-MM-dd HH:mm:ss")
    private LocalDateTime createTime;
​
    @JsonFormat(locale = "zh", timezone = "GMT+8", pattern = "yyyy-MM-dd HH:mm:ss")
    private Date updateTime;
​
    public LocalDateTime getCreateTime() {
        return createTime;
    }
​
    public void setCreateTime(LocalDateTime createTime) {
        this.createTime = createTime;
    }
​
    public Date getUpdateTime() {
        return updateTime;
    }
​
    public void setUpdateTime(Date updateTime) {
        this.updateTime = updateTime;
    }
}

After testing the results, it is found that both Date type and LocalDateTime type are successfully formatted, but there is still a problem, which is still cumbersome. The Date field of each entity class needs to be annotated with @ JsonFormat, and the repeated workload is not small. And look down~

2. Global configuration (1)

Spring boot has provided us with date format ${spring. Jackson. Date format: yyyy MM DD HH: mm: SS}. Here we need to conduct global configuration, which is relatively simple, and we don't need to add @ JsonFormat annotation on entity class properties.

/**
 * @Author: xiaofu
 * @Description:
 */
public class OrderInfo {
​
    //@JsonFormat(locale = "zh", timezone = "GMT+8", pattern = "yyyy-MM-dd HH:mm:ss")
    private LocalDateTime createTime;
​
    //@JsonFormat(locale = "zh", timezone = "GMT+8", pattern = "yyyy-MM-dd HH:mm:ss")
    private Date updateTime;
​
    public LocalDateTime getCreateTime() {
        return createTime;
    }
​
    public void setCreateTime(LocalDateTime createTime) {
        this.createTime = createTime;
    }
​
    public Date getUpdateTime() {
        return updateTime;
    }
​
    public void setUpdateTime(Date updateTime) {
        this.updateTime = updateTime;
    }
}

Just define a Configuration class with @ Configuration and inject two beans to complete the global date formatting. This method is also used in my project at present.

/**
 * @Author: xiaofu
 * @Description:
 */
@Configuration
public class LocalDateTimeSerializerConfig {
​
    @Value("${spring.jackson.date-format:yyyy-MM-dd HH:mm:ss}")
    private String pattern;
​
    @Bean
    public LocalDateTimeSerializer localDateTimeDeserializer() {
        return new LocalDateTimeSerializer(DateTimeFormatter.ofPattern(pattern));
    }
​
    @Bean
    public Jackson2ObjectMapperBuilderCustomizer jackson2ObjectMapperBuilderCustomizer() {
        return builder -> builder.serializerByType(LocalDateTime.class, localDateTimeDeserializer());
    }
}

This method can support the coexistence of Date type and LocalDateTime type, so there is a problem that the global time format is yyyy MM DD HH: mm: SS, but some fields need yyyy MM DD format?

It needs to be used in conjunction with the @ JsonFormat annotation. Add the @ JsonFormat annotation to a specific field attribute. Because the @ JsonFormat annotation has a higher priority, it will be based on the time format of the @ JsonFormat annotation.

3. Global configuration (2)

This global configuration is implemented in the same way as the above. However, it should be noted that after using this configuration, the @ JsonFormat annotation manually configured for the field will no longer take effect.

/**
 * @Author: xiaofu
 * @Description:
 */
public class OrderInfo {
​
    //@JsonFormat(locale = "zh", timezone = "GMT+8", pattern = "yyyy-MM-dd HH:mm:ss")
    private LocalDateTime createTime;
​
    //@JsonFormat(locale = "zh", timezone = "GMT+8", pattern = "yyyy-MM-dd HH:mm:ss")
    private Date updateTime;
​
    public LocalDateTime getCreateTime() {
        return createTime;
    }
​
    public void setCreateTime(LocalDateTime createTime) {
        this.createTime = createTime;
    }
​
    public Date getUpdateTime() {
        return updateTime;
    }
​
    public void setUpdateTime(Date updateTime) {
        this.updateTime = updateTime;
    }
}
/**
 * @Author: xiaofu
 * @Description:
 */
@Configuration
public class LocalDateTimeSerializerConfig {
​
    @Value("${spring.jackson.date-format:yyyy-MM-dd HH:mm:ss}")
    private String pattern;
​
    @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;
    }
​
    public class LocalDateTimeSerializer extends JsonSerializer<LocalDateTime> {
        @Override
        public void serialize(LocalDateTime value, JsonGenerator gen, SerializerProvider serializers) throws IOException {
            gen.writeString(value.format(ofPattern(pattern)));
        }
    }
​
    public class LocalDateTimeDeserializer extends JsonDeserializer<LocalDateTime> {
        @Override
        public LocalDateTime deserialize(JsonParser p, DeserializationContext deserializationContext) throws IOException {
            return LocalDateTime.parse(p.getValueAsString(), ofPattern(pattern));
        }
    }
}

This article shares a small trick in the development of Springboot projects, and also tuckles to make complaints about project optimization.

Optimizing other people's code is a painful thing, but in this process, we can learn a lot of skills, which is also very helpful for the improvement of personal skills, because they are all dry goods that can actually improve the development efficiency.

Source network, only for learning, if there is infringement, contact delete.

I have compiled the interview questions and answers into PDF documents, as well as a set of learning materials, including Java virtual machine, spring framework, java thread, data structure, design pattern, etc., but not limited to this.

Focus on the official account [java circle] for information, as well as daily delivery of quality articles.

file

Posted by johnmess on Thu, 23 Apr 2020 02:59:06 -0700