将杰森日期转换为杰克逊的众多日期之一

时间:2017-01-06 05:51:33

标签: javascript json spring-boot jackson

我有一个使用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更加宽容(以及如何连接它!)或者有没有办法在客户端强制执行此操作,哪里看起来更自然?你可以分享的任何例子都会有所帮助

1 个答案:

答案 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;