如何使用 EL 计算 (JSR 380) 约束消息中数组的长度?

问题描述 投票:0回答:1

我有一个限制,我想使用 EL 来根据情况调整消息。根据数组的长度,我想显示不同的消息。但是,我无法获取该数组的长度。

我做错了什么?

import org.junit.jupiter.api.Test;
import javax.validation.*;
import java.lang.annotation.*;
import static org.assertj.core.api.Assertions.assertThat;

public class FooTest {
    private final Validator validator = Validation.buildDefaultValidatorFactory().getValidator();

    @Test
    public void foo() {
        var violations = validator.validate(new ObjectWithFoo());
        assertThat(violations).extracting("message")
            .containsExactly("Field value should be foo");
    }

    @Test
    public void foos() {
        var violations = validator.validate(new ObjectWithFoos());
        assertThat(violations).extracting("message")
            .containsExactly("Field value should be one of [foo, bar, baz]");
    }

    @Foo(foos = {"foo"})
    private static class ObjectWithFoo{}

    @Foo(foos = {"foo", "bar", "baz"})
    private static class ObjectWithFoos{}

    @Constraint(validatedBy = FooValidator.class)
    @Target({ElementType.TYPE})
    @Retention(RetentionPolicy.RUNTIME)
    public @interface Foo{
        Class<?>[] groups() default {};
        Class<? extends Payload>[] payload() default {};

        String[] foos();

        // This is the message I want to tune to the length of the array.
        // If the array contains just one element, I want to show a different message.
        // Note that 'one of foos' is a placeholder; I still need to figure out 
        // how to display the array in that case.
        String message() default "Field value should be ${foos.length == 1 ? foos[0] : 'one of foos'}";
        @Target({ElementType.TYPE})
        @Retention(RetentionPolicy.RUNTIME)
        @interface List {
            Foo[] value();
        }
    }

    public static class FooValidator implements ConstraintValidator<Foo, Object> {
        @Override
        public void initialize(Foo constraintAnnotation) {
        }

        @Override
        public boolean isValid(Object o, ConstraintValidatorContext constraintValidatorContext) {
            return false; // for this test, we want the validation to fail
        }
    }
}

不幸的是,这会引发异常:

20:03:52.810 [main] WARN org.hibernate.validator.internal.engine.messageinterpolation.ElTermResolver - 
HV000148: An exception occurred during evaluation of EL expression '${foos.length == 1 ? foos[0] : 'one of $foos'}'
java.lang.NumberFormatException: For input string: "length"
    at java.base/java.lang.NumberFormatException.forInputString(NumberFormatException.java:65)
    at java.base/java.lang.Integer.parseInt(Integer.java:652)
java el check-constraints jsr380
1个回答
0
投票

感谢 Thiago Henrique Hupner 和 Mark Thomas 的努力,EL 6 及更高版本中添加了对 称为

length
的数组属性的支持。

© www.soinside.com 2019 - 2024. All rights reserved.