Spring @RequestParam DateTime 格式为 ISO 8601 日期可选时间

Spring @RequestParam DateTime format as ISO 8601 Date Optional Time

我正在为我的服务使用 Spring 框架 API 和 org.joda.time.DateTime 用于日期时间解析。具体来说,我使用的是 ISOFormatter.dateOptionalTimeParser(),它允许用户灵活地只使用日期,或者同时使用日期和时间,这是一项要求。

相信我,我已经看到了所有这些相关的问题,我已经可以告诉人们这些问题会指向我,例如this and

之前我是把日期取为String,然后在服务层使用上面提到的joda格式化程序处理,但是现在我想在控制器中添加请求验证,这意味着如果请求在语法上不正确,请求甚至不应该进入服务层。

我试过使用 @DateTimeFormat(iso = ISO.DATE_TIME) 的多种变体,并在格式中指定 pattern 字符串,但无论如何都没有成功。

@RequestMapping(value = URIConstants.TEST_URL, method = RequestMethod.GET)
public @ResponseBody String getData(@RequestParam(required = false) DateTime from,
                                    @RequestParam(required = false)  DateTime to)  {
    return dataService.fetchDataFromDB(from, to);
}

我应该怎么做才能确保从用户那里获得的日期符合 ISO 8601 dateOptionalTime 格式?我可以应用多种模式来实现吗?

我最终为此创建了一个 POJO,我在其中使用 ISODateTimeFormat.dateOptionalTimeParser():

String 解析时间
public class DateOptionalTime {

    private DateTime date;

    private DateTimeFormatter formatter = ISODateTimeFormat.dateOptionalTimeParser();

    public DateOptionalTime() {
    }

    public DateOptionalTime(String date) {
        if (date != null) {
            this.setDate(formatter.parseDateTime(date));
        }
    }

    public DateTime getDate() {
        return date;
    }

    public void setDate(DateTime date) {
        this.date = date;
    }

    public LocalDateTime getLocalDateTime() {
        return date.toLocalDateTime();
    }


}

而在控制器中,我是这样使用的:

@RequestMapping(value = URIConstants.TEST_URL, method = RequestMethod.GET)
public @ResponseBody String getData(@RequestParam(required = false) DateOptionalTime from,
                                    @RequestParam(required = false)  DateOptionalTime to)  {
    return dataService.fetchDataFromDB(from, to);
}

根据ISO标准验证日期格式,格式不正确returnsBAD_REQUEST状态

您也可以创建一个转换器来处理它。我在下面的示例中使用了 OffsetDateTime,但可以很容易地用 LocalDateTime 替换它。详细文章请参考这篇url - http://www.baeldung.com/spring-mvc-custom-data-binder

甚至我也为此苦苦挣扎了一段时间,但它没有用。诀窍是使用 @Component 注释并为我完成。

import java.time.OffsetDateTime;
import java.time.format.DateTimeFormatter;

import org.springframework.core.convert.converter.Converter;
import org.springframework.stereotype.Component;

@Component
public class OffsetDateTimeConverter implements Converter<String, OffsetDateTime> {

    @Override
    public OffsetDateTime convert(final String source) {

        if (source == null || source.isEmpty()) {
            return null;
        }

        return OffsetDateTime.parse(source, DateTimeFormatter.ISO_OFFSET_DATE_TIME);
    }
}