0

我有一个使用 Spring 框架及其验证器对表单的输入值进行完整性检查的 Groovy 项目。我想让 Spring 通过内置的输入表单字段旁边填充错误消息${status.errorMessage};但是,我只能让它在我的模型对象(来自控制器)中填充“errorMessages”。所以让我们看一些代码。

登录.jsp:

<form method="post" action="<c:url value="/login" />">
    <spring:bind path="request.username">
        <label for="username"><fmt:message key="login.username"/>:
            <input type="text" id="username" size="20" maxlength="50" name="username" value="${request.username}"/>
        </label>
        <%-- This part does NOT display the validation errors. --%>
        <c:if test="${status.error}"><span class="error">${status.errorMessage}</span></c:if>
    </spring:bind>

    <spring:bind path="request.password">
        <label for="password"><fmt:message key="login.password"/>:
            <input type="password" id="password" size="20" maxlength="30" name="password" />
        </label>
        <%-- This part does NOT display the validation errors. --%>
        <c:if test="${status.error}"><span class="error">${status.errorMessage}</span></c:if>
    </spring:bind>

    <input id="login" type="submit" value="Login"/>
</form>

<%-- This part does display the validation errors. --%>
<c:if test="${ec > 0}">
    <p>
        <c:forEach items="${errorCodes}" var="error">
            <span class="error"><fmt:message key="${error.defaultMessage}"/></span><br/>
        </c:forEach>
    </p>
</c:if>

登录控制器.groovy:

@RequestMapping(method = RequestMethod.GET, value = '/')
ModelAndView defaultView() {
    ModelMap model = new ModelMap()
    model.addAttribute('request', new LoginRequest())
    new ModelAndView('login', model)
}

@RequestMapping(method = RequestMethod.POST, value = '/login')
ModelAndView login(
        LoginRequest loginRequest, HttpServletResponse response,
        HttpSession session, BindingResult br, ModelMap model
) {
    validator.validate(loginRequest, br)

    if (br.hasErrors()) {
        model.addAttribute('request', loginRequest)
        return returnWithError(br, model, 'login')
    }
    ...
}

private ModelAndView returnWithError(BindingResult br, ModelMap model, String redirectTo) {
    br.allErrors.each {error ->
        log.error(error.toString())
    }

    def objectErrors = br.allErrors.findAll {e -> e instanceof ObjectError}

    model.addAttribute('ec', br.errorCount)
    model.addAttribute('errorCodes', objectErrors)
    new ModelAndView(redirectTo, model)
}

LoginRequestValidator.groovy:

@Override
void validate(Object o, Errors errors) {
    ValidationUtils.rejectIfEmpty(errors, 'username', 'username.empty', 'username.empty')
    ValidationUtils.rejectIfEmpty(errors, 'password', 'password.empty', 'password.empty')
}

我错过了 Spring Magic [TM] 的哪一部分?

4

3 回答 3

3

我认为您的 BindingResult 对象应该是紧跟在您的 LoginRequest 对象之后的参数。请参阅http://static.springsource.org/spring/docs/3.0.x/reference/mvc.html#mvc-ann-requestmapping,特别是示例 15.1。BindingResult 和 @ModelAttribute 的排序无效

于 2012-08-20T04:42:51.603 回答
0

查看@RequestMapping 上的Javadoc,因为我发现它是该主题的最佳: http: //static.springsource.org/spring/docs/3.0.x/api/org/springframework/web/bind/annotation/RequestMapping.html

尝试以下操作:

ModelAndView login(
        @Valid LoginRequest loginRequest, HttpServletResponse response,
        HttpSession session, BindingResult br, ModelMap model
) {}

请参阅Spring 中的 @Valid 注解表示什么?

如果这不起作用,您应该尝试将一些代码转换为纯 Java 并运行调试器以查看发生了什么(我知道这不是一个答案,而只是一个想法)。

于 2012-08-21T18:09:45.583 回答
0

也许您会发现这些来自kgiannakakis的帖子非常有用。它解释了这些功能的用途以及如何处理在Spring 3.1 文档中进行了解释。

添加类似的东西可能会奏效,不是吗?

@Controller
public class MyController {

    @InitBinder
    protected void initBinder(WebDataBinder binder) {
        binder.setValidator(new FooValidator());
    }

    @RequestMapping("/foo", method=RequestMethod.POST)
    public void processFoo(@Valid Foo foo) { ... }

}

看看 SpringSource 博客,尤其是这些关于数据绑定新特性的文章。它可以为您的验证过程添加一些新外观。

于 2012-08-22T18:03:24.123 回答