ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • 스프링 부트 배치, RestAPI 데이터 읽기
    Spring Boot 2019. 6. 7. 20:42

    스프링 배치의 ItemReader는 파일/XML/DB에서 데이터를 읽기 위한
    전용 클래스를 제공하지만 RestAPI로 다른시스템의 데이터를 읽어오는
    전용 클래스는 아직 없다고 한다.

    예) JdbcCursorItemReader : DB에서 데이터 조회하는 클래스

    Rest 클라이언트 기능은 스프링에서 제공하는 RestTemplate를
    이용하면 간단하게 구현 가능하다.

    다음은 스프링 부트 배치 예시이다.

    (참고 url : //https://www.petrikainulainen.net/programming/spring-framework/spring-batch-tutorial-reading-information-from-a-rest-api/)

    //먼저 DTO를 간단하게 만든다. RestAPI로 읽어온 데이터를 담고, 쓰기 위한 용도이다.
    //MyDTO.java 파일
    @Getter
    @Setter
    @ToString
    public class MyDTO {//롬복을 사용
        private String id;
        private String name;
    }
    
    //스프링 부트 배치로 Job을 설정한다.
    //testJobConfiguration.java 파일
    
    @Slf4j
    @RequiredArgsConstructor
    @Configuration
    public class testJobConfiguration {
        private final JobBuilderFactory jobBuilderFactory;//Job 생성자
        private final StepBuilderFactory stepBuilderFactory;//Step 생성자
        private final DataSource dataSource;//데이터 소스, 오라클 jdbc 사용
        private static final int CHUNKSIZE = 5; //쓰기 단위인 청크사이즈
    
        private List<MyDTO> collectData = new ArrayList<>(); //Rest로 가져온 데이터를 리스트에 넣는다.
        private boolean checkRestCall = false; //RestAPI 호출여부 판단
        private int nextIndex = 0;//리스트의 데이터를 하나씩 인덱스를 통해 가져온다.
    
        @Bean
        public Job  testJob(){
            return jobBuilderFactory.get("testJob")
                    .start(collectStep())
                    .build();
        }
    
        @Bean
        public Step collectStep(){
            return stepBuilderFactory.get("collectStep")
                    .<MyDTO, MyDTO>chunk(5)
                    .reader(restCollectReader())
                    .writer(collectWriter())
                    .build();
        }
    
        //Rest API로 데이터를 가져온다.
        @Bean
        public ItemReader<MyDTO> restItCollectReader(){
            return new ItemReader<MyDTO>(){
                @Override
                public MyDTO read() throws Exception, UnexpectedInputException, ParseException, NonTransientResourceException {
                    if (checkRestCall == false){//한번도 호출 않았는지 체크
                        String uri = "http://localhost:8080/api/test/userlist"; //로컬에서 Rest Server용 프로그램을 하나 생성후 기동해둔다.
                        RestTemplate restTemplate = new RestTemplate();
                        MyDTO[] retArray = restTemplate.getForObject(uri, MyDTO[].class); //호출 결과를 우선 배열로 받고, 리스트로 변환
                        collectData = Arrays.asList(retArray);//배열을 리스트로 변환
                        log.info("Rest Call result : >>>>>>>" + collectData);
                        checkRestCall = true;//다음 read() 부터는 재호출 방지하기 위해 true로 변경
                    }
    
                    MyDTO nextCollect = null; //ItemReader는 반복문으로 동작한다. 하나씩 Writer로 전달해야 한다.
    
                    if (nextIndex < collectData.size()) {//전체 리스트에서 하나씩 추출해서, 하나씩 Writer로 전달
                        nextCollect = collectData.get(nextIndex);
                        nextIndex++;
                    }
                    return nextCollect;//DTO 하나씩 반환한다. Rest 호출시 데이터가 없으면 null로 반환.
                }
            };
        }
    
        @Bean // beanMapped()를 사용할때는 필수
        public JdbcBatchItemWriter<MyDTO> itCollectWriter(){// 오라클 db에 데이터를 쓴다.
            return new JdbcBatchItemWriterBuilder<MyDTO>()
                    .dataSource(dataSource)
                    .sql("INSERT INTO MYUSER (ID, NAME) values (:id, :name)")
                    .beanMapped()
                    .build();
        }
    }

     

     

Designed by Tistory.