Jun 01, 2021 Article blog
1. First, @JsonFormat annotations
2. Second, @JsonComponent notes (recommended)
The article is reproduced from the public number: Something inside the programmer
Time formatting is used very frequently in projects, and when our
API
interface returns results, it requires special formatting of one of the
date
field properties, often using
SimpleDateFormat
tool.
SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd");
Date stationTime = dateFormat.parse(dateFormat.format(PayEndTime()));
But once there are more places to deal with, not only
CV
operations are frequent, but also a lot of repetitive bloated code, and if you can configure the time format uniformly, you can save more time to focus on business development.
Maybe a lot of people think that uniform formatting time is very simple ah, like the next configuration on the line, but in fact this approach only works for
date
type.
spring.jackson.date-format=yyyy-MM-dd HH:mm:ss
spring.jackson.time-zone=GMT+8
While the time and date
API
used in many projects are confusing,
java.util.Date
java.util.Calendar
and
java.time LocalDateTime
exist, global time formatting must be compatible with both old and new
API
Look at the format of the time field that the interface returns before configuring the global time format.
@Data
public class OrderDTO {
private LocalDateTime createTime;
private Date updateTime;
}
Obviously doesn't meet the display requirements on the page (why doesn't someone lift the bar to allow the front end to parse the time, I can only say that the pajama code is much easier than convincing people)
@JsonFormat
annotation is strictly not called global time formatting, it should be called partial formatting, because
@JsonFormat
annotations need to be used on the time field of the entity class, and only with the corresponding entity class, the corresponding field can 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;
}
After
@JsonFormat
fields are added @JsonFormat annotations,
LocalDateTime
and
Date
time formatting succeeds.
This is one of my personal recommendations, and I see that using
@JsonFormat
annotations is not fully global time formatting, so let's use
@JsonComponent
annotations to customize a global formatting class to format
Date
and
LocalDate
types, respectively.
@JsonComponent
public class DateFormatConfig {
@Value("${spring.jackson.date-format:yyyy-MM-dd HH:mm:ss}")
private String pattern;
/**
* @author xiaofu
* @description date 类型全局时间格式化
* @date 2020/8/31 18:22
*/
@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);
};
}
/**
* @author xiaofu
* @description LocalDate 类型全局时间格式化
* @date 2020/8/31 18:22
*/
@Bean
public LocalDateTimeSerializer localDateTimeDeserializer() {
return new LocalDateTimeSerializer(DateTimeFormatter.ofPattern(pattern));
}
@Bean
public Jackson2ObjectMapperBuilderCustomizer jackson2ObjectMapperBuilderCustomizer() {
return builder -> builder.serializerByType(LocalDateTime.class, localDateTimeDeserializer());
}
}
This approach works when you see two time types,
Date
and
LocalDate
formatted successfully.
But there's also a question, what if I actually have a field in development that I don't want to use to format the time style globally, and I want to customize the format?
That needs to be used in conjunction with
@JsonFormat
annotations.
@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;
}
From the results, we see that
@JsonFormat
annotations have a higher priority and are dominated by the time format
@JsonFormat
annotations.
This global configuration is implemented in the same way as the above.
“
Note: After using this configuration, the field is manually configured
@JsonFormat
annotation will no longer take effect.”
@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;
}
/**
* @author xiaofu
* @description Date 时间类型装换
* @date 2020/9/1 17:25
*/
@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);
}
}
/**
* @author xiaofu
* @description Date 时间类型装换
* @date 2020/9/1 17:25
*/
@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);
}
}
}
/**
* @author xiaofu
* @description LocalDate 时间类型装换
* @date 2020/9/1 17:25
*/
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)));
}
}
/**
* @author xiaofu
* @description LocalDate 时间类型装换
* @date 2020/9/1 17:25
*/
public class LocalDateTimeDeserializer extends JsonDeserializer<LocalDateTime> {
@Override
public LocalDateTime deserialize(JsonParser p, DeserializationContext deserializationContext) throws IOException {
return LocalDateTime.parse(p.getValueAsString(), DateTimeFormatter.ofPattern(pattern));
}
}
}
Sharing a simple yet practical Springboot development technique, the so-called development efficiency is just one development trick after another, and smart programmers can always get things done with minimal code.
The above is
W3Cschool编程狮
about 3 SpringBoot time formatting methods, easy to reduce the amount of your code
related to the introduction, I hope to help you.