복붙노트

[SPRING] 스프링 MVC 검사기 주석 + 사용자 정의 유효성 검사

SPRING

스프링 MVC 검사기 주석 + 사용자 정의 유효성 검사

스프링 MVC 애플리케이션에서 작업 중이며, 스프링 MVC 밸리데이터를 기반으로 검증해야합니다. 클래스 및 설정 컨트롤러에 대한 주석을 추가하고 잘 작동하는 첫 단계. 그리고 지금은 복잡한 논리를 수행하기 위해 사용자 정의 유효성 검사기를 구현해야하지만 기존 주석을 사용하고 추가 검사를 추가하려고합니다.

내 사용자 클래스 :

public class User
{
    @NotEmpty
    private String name;

    @NotEmpty
    private String login; // should be unique
}

내 유효 검사기 :

@Component
public class UserValidator implements Validator
{

    @Autowired
    private UserDAO userDAO;

    @Override
    public boolean supports(Class<?> clazz)
    {
        return User.class.equals(clazz) || UsersForm.class.equals(clazz);
    }

    @Override
    public void validate(Object target, Errors errors)
    {
        /*
        ValidationUtils.rejectIfEmptyOrWhitespace(errors, "name", "NotEmpty.user");
        ValidationUtils.rejectIfEmptyOrWhitespace(errors, "login", "NotEmpty.user");
        */
        User user = (User) target;
        if (userDAO.getUserByLogin(user.getLogin()) != null) {
            errors.rejectValue("login", "NonUniq.user");
        }
    }
}

내 컨트롤러 :

@Controller
public class UserController
{
    @Autowired
    private UserValidator validator;

    @InitBinder
    protected void initBinder(final WebDataBinder binder)
    {
        binder.setValidator(validator);
    }

    @RequestMapping(value = "/save")
    public ModelAndView save(@Valid @ModelAttribute("user") final User user,
            BindingResult result) throws Exception
    {
        if (result.hasErrors())
        {
            // handle error
        } else
        {
            //save user
        }
    }
}

그렇다면 사용자 정의 검사기와 주석을 함께 사용할 수 있습니까? 그리고 그렇다면 어떻게?

해결법

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

    1.이 질문은 일종의 오래된 질문이지만, Google 직원에게는 ...

    이 질문은 일종의 오래된 질문이지만, Google 직원에게는 ...

    setValidator 대신에 addValidators를 사용해야한다. 다음과 같이 :

    @InitBinder
    protected void initBinder(final WebDataBinder binder) {
        binder.addValidators(yourCustomValidator, anotherValidatorOfYours);
    }
    

    추신 : addValidators 여러 매개 변수를 허용 (줄임표)

    체크 아웃하면 org.springframework.validation.DataBinder 소스가 표시됩니다.

    public class DataBinder implements PropertyEditorRegistry, TypeConverter {
    
        ....
    
        public void setValidator(Validator validator) {
            assertValidators(validator);
            this.validators.clear();
            this.validators.add(validator);
        }
    
        public void addValidators(Validator... validators) {
            assertValidators(validators);
            this.validators.addAll(Arrays.asList(validators));
        }
    
        ....
    
    }
    

    보시다시피 setValidator는 기존 (기본) 유효성 검사기를 지우므로 @Valid 주석은 예상대로 작동하지 않습니다.

  2. ==============================

    2.문제를 올바르게 이해하면 사용자 정의 유효성 검사기를 사용하자마자 @NotEmpty 주석의 기본 유효성 검사가 더 이상 발생하지 않습니다. 이는 스프링을 사용할 때 일반적입니다. 기본적으로 주어진 functionnality를 오버라이드하는 경우 명시 적으로 호출해야합니다.

    문제를 올바르게 이해하면 사용자 정의 유효성 검사기를 사용하자마자 @NotEmpty 주석의 기본 유효성 검사가 더 이상 발생하지 않습니다. 이는 스프링을 사용할 때 일반적입니다. 기본적으로 주어진 functionnality를 오버라이드하는 경우 명시 적으로 호출해야합니다.

    LocalValidatorFactoryBean을 생성하고 메시지 소스가있는 경우이를 삽입해야합니다. 그런 다음 기본 유효성 검사기를 사용자 정의 유효성 검사기에 삽입하고 주석 유효성 검사를 위임자에게 위임합니다.

    java 구성을 사용하면 다음과 같이 보일 수 있습니다.

    @Configuration
    public class ValidatorConfig {
        @Autowired
        private MessageSource messageSource;
    
        @Bean
        public Validator basicValidator() {
            LocalValidatorFactoryBean validator = new LocalValidatorFactoryBean();
            validator.setValidationMessageSource(messageSource);
            return validator;
        }
    }
    

    그런 다음이를 사용하도록 UserValidator를 수정합니다.

    @Component
    public class UserValidator implements Validator
    {
    
        @Autowired
        @Qualifier("basicValidator")
        private Validator basicValidator;
    
        @Autowired
        private UserDAO userDAO;
    
        // ...
    
        @Override
        public void validate(Object target, Errors errors)
        {
            basicValidator.validate(target, errors);
            // eventually stop if any errors
            //  if (errors.hasErrors()) { return; }
            User user = (User) target;
            if (userDAO.getUserByLogin(user.getLogin()) != null) {
                errors.rejectValue("login", "NonUniq.user");
            }
        }
    }
    
  3. ==============================

    3.그럼 저를 위해

    그럼 저를 위해

     @InitBinder
    protected void initBinder(final WebDataBinder binder)
    {
        binder.setValidator(validator);
    }
    

    끝내기

    @Valid @ModelAttribute("user") final User user,
            BindingResult result
    

    그리고 함수 make에서

    validator.validate(user,result)
    

    이렇게하면 @Valid와 함께 기본 유효성 검사를 사용하게되며, 이후에는보다 복잡한 유효성 검사를 수행하게됩니다.

    initBinder를 사용하면 복잡한 논리를 사용하여 유효성을 설정하고 기본 논리를 적용 할 수 있습니다.

    어쩌면 틀렸어, 나는 항상 유효성 검사기없이 @Valid를 사용한다.

  4. from https://stackoverflow.com/questions/25075683/spring-mvc-validator-annotation-custom-validation by cc-by-sa and MIT license