SrpingBoot中jackson格式化LocalDate、Date⽇期类型
摘要:
最近在学习Springboot框架,在⽤jackson格式化实体类中Date和LocalDate时,遇到了⼀系列问题,在此做下记录。
1.LocalDate
从Java 8之后,Java.time包下,添加了⽇期处理类
新增的⽇期jar主要有三种:
java.time.LocalDate  ->只对年⽉⽇做出处理
java.time.LocalTime  ->只对时分秒纳秒做出处理
java.time.LocalDateTime ->同时可以处理年⽉⽇和时分秒
但是为啥还需要搞⼀套全新的处理⽇期和时间的API?是因为旧的java.util.Date⽐较难⽤:
1.java.util.Date⽉份从0开始,⼀⽉是0,⼗⼆⽉是11.java.time.LocalDate⽉份和星期都改成了enum,可以有效防⽌⽤错。
2.java.util.Date和SimpleDateFormatter都不是线程安全的,⽽LocalDate和LocalTime和最基本的String⼀样,是不变类型,不但线程安全,⽽且不能修改。
2.LocalDate⽤法
// 取当前⽇期:
LocalDate today = w(); // -> 2018-12-5
// 根据年⽉⽇取⽇期,12⽉就是12:
LocalDate crischristmas = LocalDate.of(2018, 12, 05); // -> 2014-12-25
// 根据字符串取:
LocalDate endOfFeb = LocalDate.parse("2018-12-05"); // 严格按照ISO yyyy-MM-dd验证,02写成2都不⾏,当然也有⼀个重载⽅法允许⾃⼰定义格式LocalDate.parse("2018-12-05"); // ⽆效⽇期⽆法通过:DateTimeParseException: Invalid date
3. LocalDate⽇期转换
// 取本⽉第1天:
LocalDate firstDayOfThisMonth = today.with(TemporalAdjusters.firstDayOfMonth()); // 2018-12-01
// 取本⽉第2天:
LocalDate secondDayOfThisMonth = today.withDayOfMonth(2); // 2018-12-02
// 取本⽉最后⼀天,再也不⽤计算是28,29,30还是31:
LocalDate lastDayOfThisMonth = today.with(TemporalAdjusters.lastDayOfMonth()); // 2018-12-31
// 取下⼀天:
LocalDate firstDayOf2019 = lastDayOfThisMonth.plusDays(1); // 变成了2019-01-01
// 取2019年1⽉第⼀个周⼀,这个计算⽤Calendar要死掉很多脑细胞:
LocalDate firstMondayOf2019 = LocalDate.parse("2019-01-01").with(TemporalAdjusters.firstInMonth(DayOfWeek.MONDAY)); // 2019-01-07
4.LocalTime⽤法
//LocalTime到毫秒位
LocalTime now = w();//11:25:50.095
//去掉毫秒
now.withNano(0); //11:25:50
//⽤构造⽅法创建LocalTime
LocalTime.of(10, 10, 20);
//字符串转换
LocalTime.parse("12:00:00");
5.JDBC中数据库⽇期类型跟JAVA8的新类型关联起来
SQL -> Java
-
-------------------------
date -> LocalDate
time -> LocalTime
timestamp -> LocalDateTime
6.SpringBoot中Controller中⽇期类型(Date、LocalDate)数据绑定
1.添加注解@DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss") Date time,如果⽤的是实体类,那么在实体类对应属性上添加该注解。该注解是⽤于将request中⽇期类型的参数按照pattern格式格式化,然后赋值给对应属性
7.SpringBoot中@ResponseBody注解Jackson 格式化输出⽇期
Date类型的属性格式化有以下⼏种⽅法:
1.在bean对象对应⽇期属性上添加@JsonFormat(pattern="yyyyMMdd")注解。
@JsonFormat(timezone = "GMT+8", pattern = "yyyyMMddHHmmss")
private Date createTime;
2.在l加⼊下⾯配置就可以
#时间戳统⼀转换
spring:
jackson:
date-format: yyyy-MM-dd HH:mm:ss
time-zone: GMT+8
3. LocalDate、LocalDateTime、LocalTime类型数据 格式化:
配置⽅案⼀:
定义⼀个配置类,在其中定义两个Bean,即可完成全局⽇期格式化处理,同时还兼顾了Date和LocalDateTime并存。实体类中⽇期属性不需要添加注解,Date类型属性,会由l中spring.jackson.date-format⾃动格式化,LocalDate类型的属性,则会被如下定义的LocalDateSerialize
r 格式化
@Configuration
public class LocalDateTimeSerializerConfig {
@Value("${spring.jackson.date-format}")
private String pattern ;
// ⽅案⼀
@Bean
public LocalDateSerializer localDateDeserializer() {
return new LocalDateSerializer(DateTimeFormatter.ofPattern(pattern));
}
@Bean
public Jackson2ObjectMapperBuilderCustomizer jackson2ObjectMapperBuilderCustomizer() {
return builder -> builder.serializerByType(LocalDate.class, localDateDeserializer());
}
}
实体类:
@Data
@AllArgsConstructor
@NoArgsConstructor
public class User {
private Long id;
pattern属性private String name;
private Integer age;
@DateTimeFormat(pattern = "yyyyMMdd")
private LocalDate birthday;
}
Controller:
@GetMapping("/{id}")
public User getUser(@PathVariable Long id){
UserById(id);
}
配置⽅案⼆
有时候,我们对⽇期格式要做特殊的处理,全局的格式化⽅式⽆法满⾜我们需求是,使⽤该⽅案是⾮
常好的选择,通过 @JsonFormat 注解我们可以更为精准的为⽇期字段格式化,它的优先级⽐⽅案⼀⾼,⼆者可结合使⽤
@Data
@AllArgsConstructor
@NoArgsConstructor
public class User {
private Long id;
private String name;
private Integer age;
@JsonFormat(pattern = "yyyyMMdd")
private LocalDate birthday;
public User(Long id, String name, Integer age) {
super();
this.id = id;
this.name = name;
this.age = age;
}
}
配置⽅案三
其实和第⼀种类似,只不过第⼀种的写法更加优雅简洁,如果有多种类型需要做统⼀格式化处理,这种⽅案也不是不可以考虑(经测试不能与⽅案⼆同时使⽤)
package fig;
import java.io.IOException;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import org.springframework.beans.factory.annotation.Value;
import t.annotation.Bean;
import t.annotation.Configuration;
import t.annotation.Primary;
import com.JsonGenerator;
import com.JsonParser;
import com.fasterxml.jackson.databind.DeserializationContext;
import com.fasterxml.jackson.databind.JsonDeserializer;
import com.fasterxml.jackson.databind.JsonSerializer;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.SerializerProvider;
import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule;
@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());
return objectMapper;
}
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.ValueAsString(), DateTimeFormatter.ofPattern(pattern));        }
}
}
推荐使⽤⽅案⼀与⽅案⼆
本⽂好多内容是参考了⼀下两位⼤神的⽂章
参考资料地址:

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。