我有一个使用jackson的spring boot 1.3.5 app:
" com.fasterxml.jackson.datatype:杰克逊 - 数据类型-jsr310:2.5.0"
我看到的问题是当用户以不同于预期的格式(mm / dd / yyyy)输入值并执行POST时,我得到一个令人讨厌的错误返回到UI(服务器日志中没有显示):
无法阅读文档:文字' 08-21-1999'无法解析 索引2(通过参考链: com.xxx.yyy.MyDTO [\" firstofficevisit \"]);嵌套异常是 com.fasterxml.jackson.databind.JsonMappingException:Text' 08-21-1999' 无法在索引2处解析(通过参考链: com.xxx.yyy.MyDTO [\" firstofficevisit \"])
以下是在dateOfBirth工作时提交的json,但firstofficevisit会抛出上述错误:
{
"patientId":3,
"dateOfBirth":"04/11/1984",
"firstofficevisit":"08-21-1999",
...
}
我在DTO上有这个:
@JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "MM/dd/yyyy")
private LocalDate dateOfBirth;
@JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "MM/dd/yyyy")
private LocalDate firstofficevisit;
但是,除非日期提交完全相同,否则失败。我有一个很好的Java实用程序来处理日期转换,我想知道是否有可能让我的DTO使用它:
public class DateUtil {
private static final Map<String, String> DATE_FORMAT_REGEXPS = new HashMap<String, String>() {{
put("^\\d{8}$", "yyyyMMdd");
put("^\\d{1,2}-\\d{1,2}-\\d{4}$", "dd-MM-yyyy");
put("^\\d{4}-\\d{1,2}-\\d{1,2}$", "yyyy-MM-dd");
put("^\\d{1,2}/\\d{1,2}/\\d{4}$", "MM/dd/yyyy");
put("^\\d{4}/\\d{1,2}/\\d{1,2}$", "yyyy/MM/dd");
put("^\\d{1,2}\\s[a-z]{3}\\s\\d{4}$", "dd MMM yyyy");
put("^\\d{1,2}\\s[a-z]{4,}\\s\\d{4}$", "dd MMMM yyyy");
put("^\\d{12}$", "yyyyMMddHHmm");
put("^\\d{8}\\s\\d{4}$", "yyyyMMdd HHmm");
put("^\\d{1,2}-\\d{1,2}-\\d{4}\\s\\d{1,2}:\\d{2}$", "dd-MM-yyyy HH:mm");
put("^\\d{4}-\\d{1,2}-\\d{1,2}\\s\\d{1,2}:\\d{2}$", "yyyy-MM-dd HH:mm");
put("^\\d{1,2}/\\d{1,2}/\\d{4}\\s\\d{1,2}:\\d{2}$", "MM/dd/yyyy HH:mm");
put("^\\d{4}/\\d{1,2}/\\d{1,2}\\s\\d{1,2}:\\d{2}$", "yyyy/MM/dd HH:mm");
put("^\\d{1,2}\\s[a-z]{3}\\s\\d{4}\\s\\d{1,2}:\\d{2}$", "dd MMM yyyy HH:mm");
put("^\\d{1,2}\\s[a-z]{4,}\\s\\d{4}\\s\\d{1,2}:\\d{2}$", "dd MMMM yyyy HH:mm");
put("^\\d{14}$", "yyyyMMddHHmmss");
put("^\\d{8}\\s\\d{6}$", "yyyyMMdd HHmmss");
put("^\\d{1,2}-\\d{1,2}-\\d{4}\\s\\d{1,2}:\\d{2}:\\d{2}$", "dd-MM-yyyy HH:mm:ss");
put("^\\d{4}-\\d{1,2}-\\d{1,2}\\s\\d{1,2}:\\d{2}:\\d{2}$", "yyyy-MM-dd HH:mm:ss");
put("^\\d{1,2}/\\d{1,2}/\\d{4}\\s\\d{1,2}:\\d{2}:\\d{2}$", "MM/dd/yyyy HH:mm:ss");
put("^\\d{4}/\\d{1,2}/\\d{1,2}\\s\\d{1,2}:\\d{2}:\\d{2}$", "yyyy/MM/dd HH:mm:ss");
put("^\\d{1,2}\\s[a-z]{3}\\s\\d{4}\\s\\d{1,2}:\\d{2}:\\d{2}$", "dd MMM yyyy HH:mm:ss");
put("^\\d{1,2}\\s[a-z]{4,}\\s\\d{4}\\s\\d{1,2}:\\d{2}:\\d{2}$", "dd MMMM yyyy HH:mm:ss");
}};
我的问题是日期是作为字符串发生的,并且试图验证每个排列的有效性和格式是最难的,特别是因为我有许多日期字段需要这个。
所以我不确定这方面的最佳方法 - 是否有可能让杰克逊对我的DateUtil.java更加宽容(以及如何连接它!)或者有没有办法在客户端强制执行此操作,哪里看起来更自然?你可以分享的任何例子都会有所帮助
答案 0 :(得分:1)
无法以任何格式自动解析日期。您将不得不以某种方式列出您想要按特定顺序处理的所有格式。或者如果可能,在前端强制执行特定格式。您不必将json预处理为文本以使其解析。
我知道使用Java 8和Jackson处理多种日期格式的最简单方法是使用自定义JsonDeserializer和多个可选模式。 E.g。
class LocalDateParser extends JsonDeserializer<LocalDate> {
private final DateTimeFormatter dateFormatter = new DateTimeFormatterBuilder()
.appendOptional(DateTimeFormatter.ofPattern("MM-dd-yyyy"))
.appendOptional(DateTimeFormatter.ofPattern("MM/dd/yyyy"))
.toFormatter();
@Override
public LocalDate deserialize(JsonParser jsonparser, DeserializationContext context) throws IOException {
return LocalDate.parse(jsonparser.getText(), dateFormatter);
}
}
并注释你这样的字段:
@JsonDeserialize(using = LocalDateParser.class)
public LocalDate firstofficevisit;