如何可靠地接受 Spring 形式的时间输入?

How to reliably accept time input in a Spring form?

我有一个 @Entity 有几个 java.util.Date 字段;其中两个应该是时间格式的。我需要一种接受时间的方法,最好是使用选择器,以便持久保存到我的数据库。

我尝试使用,例如,

@DateTimeFormat(pattern="hh:mm a")
private Date startTime;

除此之外,还有各种尝试添加 type="time" 等等,

...
<label for="startTime" class="sr-only">Start</label>
<form:input path="startTime" name="startTime" placeholder="Start" /
...

...但我收到 Bad Request 错误。

我知道那是什么意思,我只需要知道一种可靠的修复方法。我怎样才能可靠地接受 Spring 形式的时间输入?


其他网络信息:

Remote Address:[::1]:8080
Request URL:http://localhost:8080/shift_create/1.html
Request Method:POST
Status Code:400 Bad Request
Response Headers
view source
Cache-Control:must-revalidate,no-cache,no-store
Content-Length:307
Content-Type:text/html; charset=ISO-8859-1
Date:Mon, 10 Aug 2015 08:37:27 GMT
Server:Jetty(9.2.8.v20150217)
Request Headers
view source
Accept:text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8
Accept-Encoding:gzip, deflate
Accept-Language:en-US,en;q=0.8
Cache-Control:max-age=0
Connection:keep-alive
Content-Length:58
Content-Type:application/x-www-form-urlencoded
Cookie:JSESSIONID=1w0rkel0w4eha96edvwq7rz1m
Host:localhost:8080
Origin:http://localhost:8080
Referer:http://localhost:8080/profile.html
Upgrade-Insecure-Requests:1
User-Agent:Mozilla/5.0 (Windows NT 6.3; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/44.0.2403.130 Safari/537.36
Form Data
view source
view URL encoded
name:ThisOne
shiftDate:08/13/2015
startTime:10:10 PM

Form data source : name=ThisOne&shiftDate=08%2F13%2F2015&startTime=10%3A10+PM

向您的控制器添加一个 InitBinder 并指定您想要获取的格式:

@InitBinder
public void initBinder(WebDataBinder binder) {
    SimpleDateFormat sdf = new SimpleDateFormat("dd/MM/yyyy");
    sdf.setLenient(true);
    sdf.setTimeZone(TimeZone.getTimeZone("CET"));
    binder.registerCustomEditor(Date.class, new CustomDateEditor(sdf,true));
}

接受时间的方法原来是

  1. 为需要存储时间的实体创建一个DTO class
  2. 将字段类型切换为 String
  3. 包括用于输入的时间选择器(我使用 ClockPicker
  4. 提供根据您的时间选择器和 return 解析时间字符串的方法 Date
  5. POST上使用(4)中的方法将数据从DTO传输到要保存到数据库的实体中

大部分代码都很简单;解析部分可能如下所示:

// Time from a ClockPicker is "hh:mm"
private Date getTime(String time) {

    if (time != null)
        return makeCalendar(getTimeComponents(getTimeComponents(time))).getTime();
    return null;
}

private String[] getTimeComponents(String time) {
    return time.split(":");
}

private int[] getTimeComponents(String... time) {
    int hour = Integer.parseInt(time[0]);
    return new int[] { 
            hour, 
            Integer.parseInt(time[1]), 
            0, 
            hour >= PM ? Calendar.AM : Calendar.PM 
    };
}