-
DTO, Entity, Query Object 以 java.util.Date为主, 避免使用 java.time package 里的 LocalDate, LocalTime, LocalDateTime,…
-
Spring 预设不会对任何的字串做日期格式的转换( string -> date),所以,如果 DTO 里有 Date 类型的属性, 需要自行加上格式转换的 Annotation , Query Parameter (通常是 GET) 用 @DateTimeFormat, JSON object (POST, PATCH, PUT)里的用 @JsonFormat
-
日期的 pattern 可以依照需要自行决定, 但要尽量接近 ISO 8601 的格式,不要带T的间隔,跟Z的后缀
· 2021-01-15 ⭕️
· 2021-01-15 23:59:59 ⭕️
· 2021-01-15 23:59 ⭕️
· 2021-01-15 23 ❌
· 2021-01-15T23:59:59 ❌
· 2021-01-15’T’23:59:59 ❌
· 2021-01-05T15:21:47.245Z ❌
· 2021-01-05T15:21:47.245 ❌ -
如果只有时间没有日期的部分, 使用 String 直接处理,不要转换成 Date 会比较简单
-
swagger 默认会使用完整格式的 ISO Date ex: 2021-01-05T15:21:47.245Z, 不会认得 @DateTimeFormat 跟 @JsonFormat, 所以,必须要在 SpringFox 的 Annotation 中额外使用 example 来指明日期格式,不然前端会不知道 API 需要传入什么样的日期格式
Domain layer 是接收 client 传入的 Query Parmeter, JSON Object 以及储存到数据库的内容, 这些通常都需要做型别转换, Spring 对 Java 8 的LocalDate, LocalTime, LocalDateTime 需要更多额外的处理,所以, Domain Layer 以 java.util.Date 为主, DTO 也可以用 String 的类型去接收日期, 但是用 String 可能就需要自己手动转型以及验证格式. 当然; 在其他不是 Domain Layer 的地方,你可以使用 java.time.
范例
Query Paramter
Query Parmeter 通常是在做查询 (HTTP GET), 参数可能是直接以日期字串格式传入, 也可能是包在 Query DTO 中传入到 controler
Query Parameter: 不管是使用 Date 物件或者是 QueryObject 物件,都是用 @DateTimeFormat, 因为它是从 Query String 转换, 不是 JSON
curl -X GET 'users?birth=2021-01-05'
使用 Request Paramter 接收 Date 的方式
@ApiOperation(value = "使用者")
@GetMapping(path = "/users")
public void downloadAgents(
@ApiParam(value = "依照出生日期查询", example = "2021-01-05") // 注意: 必须加入 example , swagger render 出来的格式才会正确
@DateTimeFormat(pattern = "yyyy-MM-dd") Date birth
) {
System.out.println(birth); // 2021-01-05
}
使用 Request Paramter 接收 QueryObject 的方式
// query dto
@ApiModel(description = "用户查询DTO")
public class UserQuery {
@ApiModelProperty(value = "依照出生日期查询", example = "2021-01-05") // 注意: 必须加入 example , swagger render 出来的格式才会正确
@DateTimeFormat(pattern = "yyyy-MM-dd")
private Date birth;
}
// controller
@ApiModelProperty(value = "查询用户")
@GetMapping(path="/users")
public void listUsers(UserQuery query) throws IOException { // 这个是 Query String, 不是 JSON
System.out.println(query.getBirth()); // 2021-01-05
}
JSON Object
controller 利用 @RequestBody 接收 JSON 物件时, 日期在 JSON 物件里会以日期字串格式呈现成为 JSON Object 的属性的值
curl -X POST users -H 'Content-Type: application/json' --data '{ "username": "kent", "birth": "2021-01-05" }'
// create dto
@ApiModel(description = "用户创建DTO")
public class UserCreateDto {
@ApiModelProperty(value="姓名")
private String username;
@ApiModelProperty(value = "出生日期", example = "2021-01-05") // 注意, 必须加入 example , swagger render 出来的格式才会正确
@JsonFormat(pattern = "yyyy-MM-dd")
private Date birth;
}
// controller
@ApiModelProperty(value = "创建新用户")
@GetMapping(path="/users")
public void listUsers(@RequestBody UserCreateDto dto) throws IOException {
System.out.println(dto.getBirth()); // 2021-01-05
}