programing

Spring-Data-Rest Validator

starjava 2023. 7. 1. 07:57
반응형

Spring-Data-Rest Validator

스프링 데이터-휴게기 프로젝트에 스프링 검증기를 추가하려고 했습니다.

저는 다음 링크를 통해 "시작하기" 애플리케이션을 설정했습니다. http://spring.io/guides/gs/accessing-data-rest/

...이제 다음 문서에 따라 사용자 정의 PeopleValidator를 추가하려고 합니다. http://docs.spring.io/spring-data/rest/docs/2.1.0.RELEASE/reference/html/validation-chapter.html

내 사용자 정의 PeopleValidator는 다음과 같습니다.

package hello;

import org.springframework.validation.Errors;
import org.springframework.validation.Validator;

public class PeopleValidator implements Validator {
    @Override
    public boolean supports(Class<?> clazz) {
        return true;
    }

    @Override
    public void validate(Object target, Errors errors) {
        errors.reject("DIE");
    }
}

...그리고 내 Application.java 클래스는 다음과 같습니다.

package hello;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Import;
import org.springframework.data.jpa.repository.config.EnableJpaRepositories;
import org.springframework.data.rest.webmvc.config.RepositoryRestMvcConfiguration;

@Configuration
@EnableJpaRepositories
@Import(RepositoryRestMvcConfiguration.class)
@EnableAutoConfiguration
public class Application {

    public static void main(String[] args) {
        SpringApplication.run(Application.class, args);
    }

    @Bean
    public PeopleValidator beforeCreatePeopleValidator() {
        return new PeopleValidator();
    }
}

나는 그것을 다음과 같이 게시할 것으로 예상합니다.http://localhost:8080/peoplePeopleValidator에서 모든 항목을 거부하므로 URL에 오류가 발생할 수 있습니다.그러나 오류가 발생하지 않으며 검증자가 호출되지 않습니다.

또한 스프링 데이터-휴지기 설명서의 섹션 5.1에 나와 있는 대로 수동으로 검증기를 설정해 보았습니다.

제가 무엇을 빠뜨리고 있나요?

따라서 "저장" 전후 이벤트는 PUT 및 PATCH에서만 발생하는 것으로 보입니다.POST 중에 "생성" 전후 이벤트가 발생합니다.

저는 그것을 수동으로 다시 시도했습니다.configureValidatingRepositoryEventListener오버라이드해서 작동했습니다.저는 제가 직장에서 여기 집에서 하는 것과 다르게 무엇을 하고 있는지 잘 모르겠습니다.내일 찾아봐야겠습니다.

다른 사람들이 왜 그것이 작동하지 않는지에 대한 제안을 한다면 저는 정말 듣고 싶습니다.

참고로 새 Application.java 클래스는 다음과 같습니다.

package hello;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Import;
import org.springframework.data.jpa.repository.config.EnableJpaRepositories;
import org.springframework.data.rest.core.event.ValidatingRepositoryEventListener;
import org.springframework.data.rest.webmvc.config.RepositoryRestMvcConfiguration;

@Configuration
@EnableJpaRepositories
@Import(RepositoryRestMvcConfiguration.class)
@EnableAutoConfiguration
public class Application extends RepositoryRestMvcConfiguration {

    public static void main(String[] args) {
        SpringApplication.run(Application.class, args);
    }

    @Override
    protected void configureValidatingRepositoryEventListener(ValidatingRepositoryEventListener validatingListener) {
        validatingListener.addValidator("beforeCreate", new PeopleValidator());
    }
}

이 기능은 현재 구현되지 않은 것 같습니다(2.3.0). 안타깝게도 이벤트 이름에 대한 상수가 없습니다. 그렇지 않으면 아래 솔루션이 그렇게 취약하지 않을 것입니다.

Configuration올바르게 명명된 모든 항목 추가Validator에게 꼭 필요한 것.ValidatingRepositoryEventListener올바른 이벤트를 사용합니다.

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Map;

import org.springframework.beans.factory.InitializingBean;
import org.springframework.beans.factory.ListableBeanFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.rest.core.event.ValidatingRepositoryEventListener;
import org.springframework.validation.Validator;

@Configuration
public class ValidatorRegistrar implements InitializingBean {

    private static final List<String> EVENTS;
    static {
        List<String> events = new ArrayList<String>();
        events.add("beforeCreate");
        events.add("afterCreate");
        events.add("beforeSave");
        events.add("afterSave");
        events.add("beforeLinkSave");
        events.add("afterLinkSave");
        events.add("beforeDelete");
        events.add("afterDelete");
        EVENTS = Collections.unmodifiableList(events);
    }

    @Autowired
    ListableBeanFactory beanFactory;

    @Autowired
    ValidatingRepositoryEventListener validatingRepositoryEventListener;

    @Override
    public void afterPropertiesSet() throws Exception {
        Map<String, Validator> validators = beanFactory.getBeansOfType(Validator.class);
        for (Map.Entry<String, Validator> entry : validators.entrySet()) {
            EVENTS.stream().filter(p -> entry.getKey().startsWith(p)).findFirst()
                    .ifPresent(p -> validatingRepositoryEventListener.addValidator(p, entry.getValue()));
        }
    }
}

어둠 속에서 약간의 찌르기 - 나는 사용하지 않았습니다.spring-data-rest하지만, 당신이 따르고 있는 튜토리얼을 읽고 난 후, 문제는 당신이 필요하다는 것입니다.PersonValidator조금도 아닌PeopleValidator그에 따라 모든 항목의 이름을 바꿉니다.

사용자 검증자

package hello;

import org.springframework.validation.Errors;
import org.springframework.validation.Validator;

public class PersonValidator implements Validator {
    @Override
    public boolean supports(Class<?> clazz) {
        return true;
    }

    @Override
    public void validate(Object target, Errors errors) {
        errors.reject("DIE");
    }
}

어플

package hello;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Import;
import org.springframework.data.jpa.repository.config.EnableJpaRepositories;
import org.springframework.data.rest.webmvc.config.RepositoryRestMvcConfiguration;

@Configuration
@EnableJpaRepositories
@Import(RepositoryRestMvcConfiguration.class)
@EnableAutoConfiguration
public class Application {

    public static void main(String[] args) {
        SpringApplication.run(Application.class, args);
    }

    @Bean
    public PersonValidator beforeCreatePersonValidator() {
        return new PersonValidator();
    }
}

또 다른 방법은 여기에 명시된 대로 주석 처리기를 사용하는 것입니다. http://docs.spring.io/spring-data/rest/docs/2.1.0.RELEASE/reference/html/events-chapter.html#d5e443

다음은 주석 처리기를 사용하는 방법의 예입니다.

import gr.bytecode.restapp.model.Agent;
import org.springframework.data.rest.core.annotation.HandleBeforeCreate;
import org.springframework.data.rest.core.annotation.HandleBeforeSave;
import org.springframework.data.rest.core.annotation.RepositoryEventHandler;
import org.springframework.stereotype.Component;

@Component
@RepositoryEventHandler(Agent.class)
public class AgentEventHandler {

    public static final String NEW_NAME = "**modified**";

    @HandleBeforeCreate
    public void handleBeforeCreates(Agent agent) {
            agent.setName(NEW_NAME);
    }

    @HandleBeforeSave
    public void handleBeforeSave(Agent agent) {
        agent.setName(NEW_NAME + "..update");
    }
}

예는 간결함을 위해 편집된 github에서 나온 것입니다.

언급URL : https://stackoverflow.com/questions/24318405/spring-data-rest-validator

반응형