带有 html 形式的 Thymeleaf 绑定日期的 Spring [英] Spring with Thymeleaf binding date in html form

查看:27
本文介绍了带有 html 形式的 Thymeleaf 绑定日期的 Spring的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个简单的表单片段,例如:

<div class="form-group"><label for="expirationDate">到期日期</label><input type="datetime-local" class="form-control" id="expirationDate"placeholder="到期日期" th:field="*{expirationTime}"/>

<button type="submit" class="btn btn-primary">提交</button></表单>

我正在传递一个填充对象 account 并且 expirationTime 是一个 LocalDateTime 字段.问题是 expirationTime 没有与传递给表单的值绑定(传递的对象是 100% 正确的).知道为什么吗?

解决方案

简而言之,Spring/Thymeleaf 没有为日期时间本地输入类型正确格式化 Java 8 日期.告诉 Spring 如何使用 @DateTimeFormat(pattern = "yyyy-MM-dd'T'HH:mm") 正确格式化值.

<小时>

注解@DateTimeFormat 告诉 Thymeleaf 在解析/格式化时如何格式化日期字符串.这包括在 HTML 输入中生成 value= 注释,以及读取表单提交的 POST 数据.datetime-local 输入类型需要一个格式为 yyyy-MM-dd'T'HH:mm 的值,因此我们将其用作模型类中的格式化程序.

模型类:

public class DateContainer {私人字符串名称;@DateTimeFormat(pattern = "yyyy-MM-dd'T'HH:mm")私人本地日期时间日期时间;公共本地日期时间 getDateTime() {返回日期时间;}public void setDateTime(LocalDateTime dateTime) {this.dateTime = 日期时间;}公共字符串 getName() {返回名称;}公共无效集名称(字符串名称){this.name = 名称;}}

控制器:

@RequestMapping("/dateTest")公共字符串日期测试(最终日期容器日期容器){if (dateContainer.getDateTime() == null) {dateContainer.setDateTime(LocalDateTime.now());}返回日期测试";}

模板:

<html xmlns:th="http://www.thymeleaf.org/"><头></头><身体><h1>你好世界!</h1><form th:action="@{/dateTest}" th:object="${dateContainer}"><label>名称:</label><input type="text" th:field="*{name}"/><label>日期时间:</label><input type="datetime-local" th:field="*{dateTime}"/><input type="submit" value="提交"/></表单></html>

HTML 生成:

<头></头><身体><h1>你好世界!</h1><form action="/dateTest"><label>名称:</label><input type="text" id="name" name="name" value=""/><label>日期时间:</label><input type="datetime-local" id="dateTime" name="dateTime" value="2017-08-28T13:01"/><input type="submit" value="Submit"/><input type="hidden" name="_csrf" value="437b30dc-a103-44d0-b4e9-791d8de62986"/></form></html>

截图:

Chrome 60 中的屏幕截图

兼容性:

日期时间本地输入类型是一种新的 HTML5 类型,并非所有浏览器都支持.查看兼容性:https://caniuse.com/#search=datetime-local

在不兼容的浏览器中,datetime-local 字段将仅显示为文本字段,并将包含日期和时间,中间有 T.这可能会导致可用性问题,具体取决于您的用例.

I have a simple snippet of form like:

<form th:action="@{'/save'}" th:object="${account}" method="post">
    <div class="form-group">
        <label for="expirationDate">Expiration date</label>
        <input type="datetime-local" class="form-control" id="expirationDate"
               placeholder="Expiration date" th:field="*{expirationTime}"/>
    </div>
    <button type="submit" class="btn btn-primary">Submit</button>
</form>

I'm passing there a filled object account and expirationTime is a LocalDateTime field. The problem is that the expirationTime is not bind with the value passed to the form (object which is passed is 100% correct). Any idea why?

解决方案

Edit: Simply put, Spring/Thymeleaf doesn't format a Java 8 date correctly for the datetime-local input type. Tell Spring how to format the value correctly with @DateTimeFormat(pattern = "yyyy-MM-dd'T'HH:mm").


The annotation @DateTimeFormat tells Thymeleaf how to format the date string when parsing/formatting. That includes producing the value= annotation in the HTML input, and reading in POST data submitted by the form. The datetime-local input type expects a value formatted yyyy-MM-dd'T'HH:mm, so we use that as the formatter in the model class.

Model Class:

public class DateContainer {

    private String name;

    @DateTimeFormat(pattern = "yyyy-MM-dd'T'HH:mm")
    private LocalDateTime dateTime;

    public LocalDateTime getDateTime() {
        return dateTime;
    }

    public void setDateTime(LocalDateTime dateTime) {
        this.dateTime = dateTime;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }
}

Controller:

@RequestMapping("/dateTest")
public String dateTest(final DateContainer dateContainer) {
    if (dateContainer.getDateTime() == null) {
        dateContainer.setDateTime(LocalDateTime.now());
    }
    return "dateTest";
}

Template:

<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org/">
<head></head>
<body>
    <h1>Hello World!</h1>
    <form th:action="@{/dateTest}" th:object="${dateContainer}">
        <label>Name: </label><input type="text" th:field="*{name}"/>
        <label>Date Time: </label><input type="datetime-local" th:field="*{dateTime}"/>
        <input type="submit" value="Submit"/>
    </form>
</body>
</html>

HTML Produced:

<!DOCTYPE html>
<html>
<head></head>
<body>
    <h1>Hello World!</h1>
    <form action="/dateTest">
        <label>Name: </label><input type="text" id="name" name="name" value="" />
        <label>Date Time: </label><input type="datetime-local" id="dateTime" name="dateTime" value="2017-08-28T13:01" />
        <input type="submit" value="Submit" />
    <input type="hidden" name="_csrf" value="437b30dc-a103-44d0-b4e9-791d8de62986" /></form>
</body>
</html>

Screenshot:

Screenshot in Chrome 60

Comptibility:

The datetime-local input type is a new HTML5 type and isn't supported in all browsers. See compatibility: https://caniuse.com/#search=datetime-local

In non-compliant browsers, the datetime-local field will simply appear as a text field, and will contain the date and time with the T in between. That may lead to usability issues depending on your use case.

这篇关于带有 html 形式的 Thymeleaf 绑定日期的 Spring的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆