简体   繁体   中英

Spring webflow partial validation not working

I am trying to implement partial validation in Spring Webflow 2.4.

I have looked at Spring webflow partial validation and the solution given there - but it does not work for me. Validation does not kick in at all when I add the groups (but works OK with no groups).

I have code and config as follows:

flow config

<view-state id="page1" view="apply/page1" model="myModel">
    <binder>
        <binding property="foo" />
    </binder>
    <transition on="next" to="page2" validate="true" validation-hints="'group1'"></transition>
</view-state>

<view-state id="page2" view="apply/page2" model="myModel">
    <binder>
        <binding property="baz" />
    </binder>
    <transition on="next" to="page3" validate="true" validation-hints="'group2'"></transition>
</view-state>

<view-state id="page3" view="apply/page3" model="myModel">
    <on-render>
        <set name="requestScope.foo" value="myModel.foo" />
        <set name="requestScope.baz" value="myModel.baz" />
    </on-render>
</view-state>

model class

public class MyModel implements Serializable {

    @NotBlank(message = "Bad foo!", groups = {Group1.class})
    private String foo;

    @NotBlank(message = "Bad baz!", groups = {Group2.class})
    private String baz;

    ...//getters and setters

    public interface Group1 {
    }

    public interface Group2 {
    }
}

html views like:

<form th:object="${myModel}" th:action="${flowExecutionUrl}" method="post">

    <div class="error" th:if="${#fields.hasErrors('*')}">
    <span th:each="err : ${#fields.errors('*')}">
        <span th:text="${err}">Input is incorrect</span>
    </span>
    </div>

    <input type="text" th:field="*{foo}"/>

    <button type="submit" name="_eventId_next">Next</button>

</form>

and

<form th:object="${myModel}" th:action="${flowExecutionUrl}" method="post">

    <div class="error" th:if="${#fields.hasErrors('*')}">
    <span th:each="err : ${#fields.errors('*')}">
        <span th:text="${err}">Input is incorrect</span>
    </span>
    </div>

    <input type="text" th:field="*{baz}"/>

    <button type="submit" name="_eventId_next">Next</button>

</form>

My intention is to use a single model for the backing form across a number of views that make up a wizard flow - doing partial validation as I go along. But when I introduce the groups needed to achieve this, the validation does not trigger at any point in the flow.

If I put typos in the validation hint names, I get errors - eg:

<transition on="next" to="page2" 
    validate="true" validation-hints="'group1zzzz'"></transition>

results in

Failed to resolve validation hint [group1zzzz]

so the groups are being picked up. But validation is not happening, and I can walk through the data-entry without triggering the errors.

I am using spring-webflow 2.4.2.RELEASE

Any ideas if I am missing something, or if this just does not work?

Update

Iv'e done some digging into the code for org.hibernate.validator.internal.engine.ValidatorImpl - where it decides if validation is required:

private boolean isValidationRequired(ValidationContext<?> validationContext,
        ValueContext<?, ?> valueContext,
        MetaConstraint<?> metaConstraint) {
    if ( validationContext.hasMetaConstraintBeenProcessed(
            valueContext.getCurrentBean(),
            valueContext.getPropertyPath(),
            metaConstraint
    ) ) {
        return false;
    }

    if ( !metaConstraint.getGroupList().contains( valueContext.getCurrentGroup() ) ) {
        return false;
    }
    return isReachable(
            validationContext,
            valueContext.getCurrentBean(),
            valueContext.getPropertyPath(),
            metaConstraint.getElementType()
    );
}

at:

    if ( !metaConstraint.getGroupList().contains( valueContext.getCurrentGroup() ) ) {
        return false;
    }

I see my instances of my group - eg 'MyModel$Group2' in both collections, but they appear not to be the same object instance, therefore the 'Collection.contains()' fails, and isValidationRequired() always returns false. See screenshots.

在此处输入图片说明

[![enter image description here][2]][2]

Agggggggggghhhhhhh - found what appears to be the cause of the issue

With spring-boot-devtools in the mix, there appears to be another classloader getting involved in loading other instances of the group marker interfaces. That is making the 'Collection.contains()' above fail every time.

If I take out spring-boot-devtools from my build stack, it works. The question now becomes:

"how to get validation groups working with spring-boot-devtools in the mix?"

在此处输入图片说明

Well, after all that, it appears that if you have spring-boot-devtools in the mix, that webflow causes some problems with the classloaders. Fix appears to be to create file:

/WEB-INF/spring-devtools.properties

and add webflow jar to the include list:

restart.include.webflow=/spring-webflow-2.4.2.RELEASE.jar

That seems to make webflow use the same devetools classloader, and validation now kicks-in OK when looking for the validation-hints interfaces.

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