因此,我正在编写一些REST API,我的一个实体具有java.util.Date类型。 我的POST端点使用JSON类型,如下所示:
{
"authorId": 7845,
"authorName": {
"first": "Dan",
"second": "Brown"
},
"birth": {
"date": "1987-10-25",
"country": "USA",
"city": "New York"
},
"description": "Very good author!"
}
我还重写了jackson deserialize
方法来处理无效的日期格式以及与此有关的所有内容:
public class CustomDateDeserializer extends StdDeserializer<Date> {
public CustomDateDeserializer() {
this(null);
}
public CustomDateDeserializer(Class t) {
super(t);
}
@Override
public Date deserialize(JsonParser jp, DeserializationContext dc) throws IOException {
String date = jp.getValueAsString();
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
sdf.setLenient(false);
Date parsed;
try {
parsed = sdf.parse(date);
} catch (ParseException e) {
throw new InvalidDateTypeException(jp.currentName(), jp.getText());
}
return parsed;
}
}
在我的DTO模型中,我将以下反序列化器完全用于此参数:
@JsonFormat(pattern = "yyyy-MM-dd")
@JsonDeserialize(using = CustomDateDeserializer.class)
@PastOrPresent(message = "Value 'date' must be past or present!")
private Date date;
在我所有中间对象(模型和DTO)的生命周期中,这个值无处不在,就像输入JSON-1987-10-25
中一样。
控制器:
@PostMapping(value = "/author/new", consumes = MediaType.APPLICATION_JSON_VALUE)
public ResponseEntity<?> addNewAuthor(@RequestBody @Valid AuthorPostDto postAuthor) {
AuthorPostDto response = authorService.addNewAuthor(postAuthor);
return new ResponseEntity<>(response, HttpStatus.CREATED);
}
服务方法:
public AuthorPostDto addNewAuthor(AuthorPostDto author) {
if (authorRepository.existsByAuthorId(author.getAuthorId())) {
throw new AuthorAlreadyExistsException();
}
Author toPost = toModelMapper.mapAuthorDtoToAuthor(author);
Author response = authorRepository.save(toPost);
return toDtoMapper.mapAuthorModelToDto_POST(response);
}
所有对象-postAuthor
(由Controller中的Jackson解析),toPost
,response
和服务返回的值-像输入JSON中一样包含Date
值-{{ 1}}。
但是在SQL中,控制器日期的返回值与前一天一起出现:1987-10-25
...
如何解决此问题?
答案 0 :(得分:0)
哦……经过与之抗争的一天,我赢了!
下一个问题是:当我发布日期为1987-10-25
的json时,它会根据需要解析为DTO。但是日期还必须有小时,毫秒和秒。因此,这就是Java在此处自动设置六个零的原因:00:00:00
。因此,我的日期看起来像这样:1987-10-25 00:00:00
。
正如我在所有中间对象(模型和DTO)的使用期间所写的那样,各处的值看起来都像这个日期:1987-10-25 00:00:00
。但是,一旦该对象离开我的应用程序,它就会在此处设置我的时区:-2。因此,对于SQL和响应JSON,我的日期是这样的:1987-10-24 22:00:00
。
要解决此问题,请在反序列化方法中将时区设置为0:
public Date deserialize(JsonParser jp, DeserializationContext dc) throws IOException {
String date = jp.getValueAsString();
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
sdf.setTimeZone(TimeZone.getTimeZone(ZoneOffset.ofHours(0))); //here
sdf.setLenient(false);
Date parsed;
try {
parsed = sdf.parse(date);
} catch (ParseException e) {
throw new InvalidDateTypeException(jp.currentName(), jp.getText());
}
return parsed;
}
现在对我有用。