【问题标题】:How to validate date format in a Spring form如何验证 Spring 表单中的日期格式
【发布时间】:2013-01-20 22:13:47
【问题描述】:

我是 Spring 新手,我正在尝试创建一个验证日期格式的表单(即:它只接受格式为“MM/dd/yyyy”的日期,如果用户输入“mm-dd-yyyy”它应该显示错误消息)。

如何使用 Spring 实现这一点?

我已经阅读了很多帖子和答案,例如 thisthis,建议在控制器中使用 @InitBinder(我尝试过但无法使其正常工作)。但是,如果我有一个不同日期的表格怎么办?或者如果我的控制器管理来自不同表单的多个发布请求,并且每个请求都需要不同的日期验证?

目前我有这个表格:

<form:form action="getReportFile.html" commandName="staticReportForm">
            <table>
                <tr>
                    <td>Reports:</td>
                </tr>
                <tr>
                    <td><form:select path="report" items="${staticReports}"/>                        
                    </td>
                </tr>
               <tr>
                   <td>Date (MM/DD/YYYY) (empty for most recent possible):<FONT color="red"><form:errors
                                path="date" /></FONT></td>
               </tr>
               <tr>
                   <td><form:input path="date" /></td>
               </tr>
               <tr>
                   <td><input type="submit" value="Submit" /></td>
               </tr>
           </table>            
       </form:form>

这将是支持表单的 bean(@DateTimeFormat 注释只有在您输入正确格式的情况下才会起作用):

public class StaticReportForm {
        @NotEmpty        
        private String report;    
        @DateTimeFormat(pattern="MM/dd/yyyy")
        private Date date;

    public String getReport() {
        return report;
    }

    public void setReport(String report) {
        this.report = report;
    }

    public Date getDate() {
        return date;
    }

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


}

【问题讨论】:

    标签: java spring jakarta-ee spring-mvc


    【解决方案1】:

    不知道spring有没有直接的方法,但是我做的方法是结合jQuery的DatePicker和InitBinder。

    在 JS 端,你创建一个:

    <form:input cssClass="datepicker" path="someProperty" readonly="true" />
    

    然后在JS中:

    $(document).ready(function() {
        $('.datepicker').datepicker();
    });
    

    在 Controller 端,像这样创建一个方法:

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

    从这里,您可以在资源包中创建 typeMismatch 消息,以创建漂亮、漂亮的消息。用户将无法手动输入字段,而只能使用 jQuery DatePicker,它将根据需要格式化日期(我认为默认为 MM/dd/yyyy)。在他们确实设法输入日期的情况下,Spring 将使用配置的 CustomEditor 将字符串从视图转换为预期的日期。如果失败,您会在 BindingResults 中收到错误(如果您将其包含在方法签名中)。正如我之前所说,您可以自定义此方法,但在资源包中设置自定义 typeMismatch 消息。

    编辑:添加更多细节作为我上面的解释显然不够清楚......

    首先,创建一个 Bean 或其他东西来充当您的模型属性(您从视图到控制器来回发送的内容)。确保其中至少有一个日期。

    public class SomeBean {
        private Date someDate;
        // ...additional properties, getters, setters...
        public Date getSomeDate() { return someDate; }
        public void setSomeDate(Date date) { somedate = date; }
    }
    

    现在您需要一个控制器。我喜欢通过

    制作我的模型属性会话属性
    @SessionAttribute.
    @Controller
    @RequestMapping("/somePath")
    @SessionAttributes({"someFormBean"})
    public class SomeController {
        /**
         * Handler method
         */
        @RequestMapping()
        public String defaultView(@ModelAttribute("someFormBean") SomeBean someFormBean, Model uiModel) {
            // Do something in your default view
            return "someDefaultView";   // Assuming you have a ViewResolver, like JspViewResolver or Tiles
        }
    
        /**
         * Submission Handler method
         */
        @RequestMapping(method = RequestMethod.POST
        public String submit(
            @ModelAttribute("someFormBean") SomeBean someFormBean, 
            BindingResult bindingResults,
            Model uiModel) {
            // bindingResults will have your errors from binding
            if(bindingResults.hasErrors()) {
                return "errorView";
            } else {
                return "successView";
            }
        }
    
        /**
         * Will be called to create your Model Attribute when its missing
         */
        @ModelAttribute("someFormBean")
        public SomeBean createSomeBean() {
            return new SomeBean();
        }
    
        /**
         * register property editors
         */
        @InitBinder
        public void initBinder(WebDataBinder binder) {
            SimpleDateFormat sdf = new SimpleDateFormat("MM/dd/yyyy");
            sdf.setLenient(true);
            binder.registerCustomEditor(Date.class, new CustomDateEditor(sdf, true));
            // You can register other Custom Editors with the WebDataBinder, like CustomNumberEditor for Integers and Longs, or StringTrimmerEditor for Strings
        }   
    }
    

    然后你需要一些视图(控制器上面的“someDefaultView”,我的代码在这个例子中是JSP,使用Spring JSTL标签库)

    <%@ taglib prefix="c"       uri="http://java.sun.com/jsp/jstl/core" %>
    <%@ taglib prefix="fmt"     uri="http://java.sun.com/jsp/jstl/fmt" %>
    <%@ taglib prefix="fn"      uri="http://java.sun.com/jsp/jstl/functions" %>
    <%@ taglib prefix="form"    uri="http://www.springframework.org/tags/form" %>
    <%@ taglib prefix="spring"  uri="http://www.springframework.org/tags" %>
    <html>
        <head>
            <script type="text/javascript" src="/resources/jquery/1.7.1/jquery-1.7.1.min.js"></script>
            <script type="text/javascript" src="resources/jquery.ui/1.8.13/jquery.ui.min.js"></script>
    
            <script type="text/javascript">
                $(document).ready(function() {
                    $('.datepicker').datepicker();
                };
            </script>
        </head>
        <body>
            <form:form modelAttribute="someFormBean">
                <form:input cssClass="datepicker" path="someDate" readonly="true" /><br />
                <form:errors path="a"/><br /><br />
                <input type="submit" value="Submit" />
            </form:form>
        </body>
    </html>
    

    再次,我建议使用 Google 的 Spring Init Binders、自定义绑定错误 (typeMismatch) 和 JSR 303 来获得额外的验证选项,大多数情况下都是很好的文档here。此外,如果您不希望字段下方出现错误,就像我在这里所做的那样,有一些方法可以在一个位置迭代所有错误,例如将所有错误放在页面顶部。它非常可配置,我可能会再输入 20 页值得深入阅读所有内容。这应该足以让您开始寻找好的示例和文档。

    【讨论】:

    • 感谢您的宝贵时间!是的,但是如果浏览器禁用了js,它可能会失败,我错了吗?我能看到的唯一方法是使用“老派”在控制器中获取参数并在那里验证它。在我的无知中,我找不到使用支持 bean 或验证器的有用方法。因此,如果您有一个包含多个日期的大型表单并希望使用 bean 来支持和验证它,您总是必须在控制器中验证日期格式? (我希望我错了)
    • 这就是 InitBinder 的作用。 Spring 将尝试使用注册的编辑器将字符串转换为日期。如果失败,它将使用错误消息填充 BindingResults。默认的很讨厌,但是你可以很容易地覆盖它,如前所述。在您的处理程序方法中,您只需查看 BindingResults 中是否有错误,以及是否将它们转发回表单页面。 Spring 已经在您的表单上处理 BindingResult 错误,并且它有很好的文档记录。甚至设置 CSS 以将字段标记为红色并发出消息。
    • 我该怎么做?你能发布我给定问题的答案吗?
    • 你是怎么做的?如果您指的是如何处理错误消息,这在static.springsource.org/spring/docs/2.5.4/reference/… 上有很好的记录
    • 一路,我想发送一个格式严格的带有日期的表格,当控制器收到它时,我可以确定它的格式正确,否则会出错显示给用户。
    猜你喜欢
    • 2013-05-20
    • 1970-01-01
    • 2021-05-29
    • 2016-05-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-04-04
    • 1970-01-01
    相关资源
    最近更新 更多