복붙노트

[SPRING] @DecimalMin 및 @DecimalMax를 사용하여 List <BigDecimal>의 유효성을 검사하는 방법

SPRING

@DecimalMin 및 @DecimalMax를 사용하여 List 의 유효성을 검사하는 방법

내 Spring 프로젝트에는 CMYK 색상 속성이있는 POJO 클래스가 있습니다. 정확히 4 개의 부동 소수점 숫자가있는 JSON 배열로이 속성을 나타내기를 바랍니다. 각 숫자는 0.0과 1.0 사이의 범위에 있어야합니다. 현재이 속성의 유효성 검사에 어려움을 겪고 있습니다.

나는 이미 조사한 결과 @DecimalMin과 @DecimalMax 주석은 Float 또는 float에 사용할 수 없습니다 (이 질문에 대한 답변 참조). 따라서 List 을 이미 버리고 List 을 대신 사용합니다.

POJO 클래스를 정리했습니다.

public class Settings {

    @NotNull
    @Size(min = 4, max = 4)
    @DecimalMin("0")
    @DecimalMax("1")
    private List<BigDecimal> cmykColor;

    public List<BigDecimal> getCmykColor() {
        return cmykColor;
    }

    public void setCmykColor(List<BigDecimal> cmykColor) {
        this.cmykColor = cmykColor;
    }
}

여기 JUnit 테스트 :

@RunWith(SpringRunner.class)
@SpringBootTest
public class SettingsTest extends Assert {

    @Autowired
    private ObjectMapper objectMapper;

    @Autowired
    private Validator validator; // from org.springframework.validation

    private Errors validate(String json) throws IOException {
        Settings settings = objectMapper.readValue(json, Settings.class);
        Errors errors = new BeanPropertyBindingResult(settings, "settings");
        validator.validate(settings, errors);
        return errors;
     }

    @Test
    public void testValid() throws IOException {
        String json = "{ \"cmykColor\": [0.5, 1.0, 0.3, 0.0] }";
        Errors errors = validate(json);
        assertEquals(0, errors.getErrorCount());
    }

    @Test
    public void testTooBig() throws IOException {
        String json = "{ \"cmykColor\": [0.5, 1.01, 0.3, 0.0] }";
        Errors errors = validate(json);
        assertEquals(1, errors.getErrorCount());    
    }

    @Test
    public void testTooMany() throws IOException {
        String json = "{ \"cmykColor\": [0.5, 1.0, 0.3, 0.0, 0.0] }";
        Errors errors = validate(json);
        assertEquals(1, errors.getErrorCount());
        assertNotNull(errors.getFieldError("cmykColor"));
    }
}

@DecimalMin ( "0") 주석과 @DecimalMax ( "1") 주석을 주석 처리 할 때, testTooBig 테스트 케이스를 제외하고 모든 테스트 케이스가 성공합니다. @DecimalMax 제약 조건에 의존합니다.

그러나 @DecimalMin ( "0") 및 @DecimalMax ( "1") 주석을 추가하면, 모든 테스트 케이스에 대해 다음과 같은 예외를받습니다. 유효성 검사기가 없다고 말합니다. DecimalMax가 List 의 유효성을 검사합니다.

javax.validation.UnexpectedTypeException: HV000030: No validator could be found for constraint 'javax.validation.constraints.DecimalMax' validating type 'java.util.List<java.math.BigDecimal>'. Check configuration for 'cmykColor'
    at org.hibernate.validator.internal.engine.constraintvalidation.ConstraintTree.getExceptionForNullValidator(ConstraintTree.java:108)
    at org.hibernate.validator.internal.engine.constraintvalidation.ConstraintTree.getInitializedConstraintValidator(ConstraintTree.java:140)
    at org.hibernate.validator.internal.engine.constraintvalidation.SimpleConstraintTree.validateConstraints(SimpleConstraintTree.java:55)
    at org.hibernate.validator.internal.engine.constraintvalidation.ConstraintTree.validateConstraints(ConstraintTree.java:73)
    at org.hibernate.validator.internal.metadata.core.MetaConstraint.doValidateConstraint(MetaConstraint.java:127)
    at org.hibernate.validator.internal.metadata.core.MetaConstraint.validateConstraint(MetaConstraint.java:120)
    at org.hibernate.validator.internal.engine.ValidatorImpl.validateMetaConstraint(ValidatorImpl.java:533)
    at org.hibernate.validator.internal.engine.ValidatorImpl.validateConstraintsForSingleDefaultGroupElement(ValidatorImpl.java:496)
    at org.hibernate.validator.internal.engine.ValidatorImpl.validateConstraintsForDefaultGroup(ValidatorImpl.java:465)
    at org.hibernate.validator.internal.engine.ValidatorImpl.validateConstraintsForCurrentGroup(ValidatorImpl.java:430)
    at org.hibernate.validator.internal.engine.ValidatorImpl.validateInContext(ValidatorImpl.java:380)
    at org.hibernate.validator.internal.engine.ValidatorImpl.validate(ValidatorImpl.java:169)
    at org.springframework.validation.beanvalidation.SpringValidatorAdapter.validate(SpringValidatorAdapter.java:104)
    at com.oce.spring.domain.SettingsTest.validate(SettingsTest.java:29)
    at com.oce.spring.domain.SettingsTest.testTooMany(SettingsTest.java:58)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    ...

그래서, @DecimalMin ( "0")과 @DecimalMax ( "1")을 어떻게 사용해야할까요? List 에서 올바르게?

해결법

  1. ==============================

    1.우리는 Hibernate Validator 6.0.x에서 컨테이너 요소 제약 조건을 구현했다.

    우리는 Hibernate Validator 6.0.x에서 컨테이너 요소 제약 조건을 구현했다.

    따라서 Hibernate Validator 6.0.x (6.0.9. 최종은 최신 버전 임) 및 Bean Validation 2.0.1로 업그레이드하고 다음과 같이합니다 :

    @Size(...)
    private List<@DecimalMin(...) @DecimalMax(...) BigDecimal> cmykColor;
    

    Hibernate Validator 6.0의 groupId는 org.hibernate.validator이다.

  2. from https://stackoverflow.com/questions/49965678/how-to-validate-a-listbigdecimal-with-decimalmin-and-decimalmax by cc-by-sa and MIT license