简体   繁体   中英

Spring JSR-303 with form:errors tag

I'm trying to use JSR-303 validation and display it's results in jsp page. Here is jsp page code piece which shows error:

<c:set var="Error">
    <form:errors path="name"/>
</c:set>
...
<spring:transform value="${Error}"/>

In the controller I have the following:

@PostMapping(params = "next")
public String next(@Valid @ModelAttribute(COMMAND_NAME) final ProjectNewDetailsCommand cmd,
                   final Errors errors,
                   final Model model,
                   final HttpServletRequest request) {

First, the solution which worked for me is writing a custom Validator class:

@Override
public void validate(Object o, Errors errors) {
    errors.pushNestedPath("project");
    ValidationUtils.rejectIfEmptyOrWhitespace(errors, "name", "error.project.creation.name.required");
    errors.popNestedPath();
}

In this case the appropriate message from messages.properties was applied and show on UI:

error.project.creation.name.required=The name must not be blank.

Here is another case when I use JSR-303 annotation:

public class Project {

    ...
    @Size(max = 100, message = "error.project.creation.size")
    private String name;

In messages.properties there is the message under key error.project.creation.size , I've also tried to add the message with key Size.command.project.name as it's stated in some of the sources. Error object in controller is also not empty and contains validation errors. But when I use this approach with JSR-303 I got the following error:

Caused by: javax.servlet.jsp.JspTagException: No message found under code 'Size' for locale 'en_US'.
    at org.springframework.web.servlet.tags.MessageTag.doEndTag(MessageTag.java:200)

Which means that for some reason Spring tries to apply Size error code instead of error.project.creation.size or Size.command.project.name . Any ideas why this is happening and how to fix this?

Finally I was able to find the source of the problem. In the code for rendering alerts, there was a spring:message tag:

<spring:message code="${error.code}" arguments="${error.arguments}"/>

If works in the following way: it looks for last code from the codes array in Errors class (see DefaultMessageSourceResolvable.getCode method) and that's why it couldn't find Size message and didn't picked up defaultMessage created by hibernate validator or the custom one.

The simple fix in this case was to add text attribute:

<spring:message code="${error.code}" arguments="${error.arguments}" text="${error.defaultMessage}"/>

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM