Spring Boot Scheduling

김호성👨🏽‍💻·2022년 10월 17일
0

Spring Boot

목록 보기
1/1

Spring Boot 에서 스케줄 만들기

다음 예제는 업비트 open api 와 Spring Boot의 스케쥴러 기능을 통하여 매 시간 마다 업비트의 다양한 정보를 Mysql 에 적재하는 방법을 서술한다.

package com.example.demo;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.scheduling.annotation.EnableAsync;
import org.springframework.scheduling.annotation.EnableScheduling;

import com.example.demo.vo.UserInfo;
@EnableScheduling
@SpringBootApplication
public class StartApplication {

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

}

먼저 spring boot 가 시작되는 지점에 "@EnableScheduling" 을 작성해준다. 그 이후 위 의 작성한 자바 파일과 같은 패키지에 스케줄 class를 아래와 같이 작성해준다.

package com.example.demo;

import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.Date;

import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.impl.client.HttpClientBuilder;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;

import com.common.Common;
/**
 * 배치 목록입니다.
 * @author kimhosung
 *
 */
@Component
public class BatchScheduler {
	Logger logger = LoggerFactory.getLogger(this.getClass());
	
	
	// 업비트에 있는 종목정보를 가져옵니다.
	@Scheduled(fixedRate = 10000)
	public void scheduleFixedRateTask() {
	        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS");
	        Date now = new Date();
	        String strDate = sdf.format(now);
	        System.out.println("작업 날짜 시간 fixedRate::" + strDate);
	        
	        Common.openapi("http://localhost:8081/batch/list");
	}
}

Common.openapi 메소드는 아래와 같이 작성하였다.

package com.common;

import java.io.IOException;

import org.apache.http.HttpResponse;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.impl.client.HttpClientBuilder;
/**
 * 공통 메소드 
 * @author kimhosung
 *
 */
public class Common {
	
	//단순 url call 
	public static void openapi(String url) {
        try {
	        HttpClient client = HttpClientBuilder.create().build();
	        HttpGet request = new HttpGet(url);
	        request.setHeader("Content-Type", "application/json");
			HttpResponse response = client.execute(request);
		} catch (IOException e) {
			e.printStackTrace();
		}
	}
}

그럼 결국 "http://localhost:8081/batch/list" url 을 통해 아래와 같이 REST 방식으로 컨트롤러를 호출할것이다. 컨트롤러의 소스는 아래와 같다.

package com.upbit.openapi;

import java.io.IOException;

import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.impl.client.HttpClientBuilder;
import org.apache.http.util.EntityUtils;
import org.json.simple.JSONArray;
import org.json.simple.JSONObject;
import org.json.simple.parser.JSONParser;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.web.bind.annotation.CrossOrigin;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;

import com.example.demo.mapper.LoginMapper;
import com.example.demo.mapper.MarketListMapper;
import com.example.demo.vo.MartListVO;
import com.example.demo.vo.UserInfo;

@RestController
@CrossOrigin(origins = "http://localhost:8080") // 컨트롤러에서 설정
@Service
public class BatchProgram {
	
	@Autowired
	MarketListMapper mrMapper;
	
	/*
	 * 마켓의 종목의 명칭을 가져옵니다. 
	 */
	@RequestMapping(value="/batch/list", method=RequestMethod.GET)
	public void testpp() {
		
		try {
	        HttpClient client = HttpClientBuilder.create().build();
	        HttpGet request = new HttpGet("https://api.upbit.com/v1/market/all");
	        request.setHeader("Content-Type", "application/json");

	        HttpResponse response = client.execute(request);
	        HttpEntity entity = response.getEntity();
	        String json = EntityUtils.toString(entity, "UTF-8");
	        
    		JSONParser parser = new JSONParser();
    		JSONArray jsonarray = (JSONArray) parser.parse(json);
    		
    		//테이블 초기
    		mrMapper.initMarketList();
    		
    		for (int i = 0; i < jsonarray.size(); i++) {
    			JSONObject obj = (JSONObject) jsonarray.get(i);
    			MartListVO vo = new MartListVO();
    			vo.setMr_cd(obj.get("market").toString());
    			vo.setEng_nm(obj.get("english_name").toString());
    			vo.setKor_nm(obj.get("korean_name").toString());
    			 try {
    				 mrMapper.insertMarketList(vo);
				} catch (Exception e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
    		}
    		
    		
		} catch (org.apache.http.ParseException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		} catch (org.json.simple.parser.ParseException e) {
			e.printStackTrace();
		}	
	}
}

여기서 중요하게 봐야될 부분은 json 형식의 파싱 방법이다.

JSONParser parser = new JSONParser();
JSONArray jsonarray = (JSONArray) parser.parse(json);

위와 같이 JSONParser를 만들고 JSON이 [] 로 시작한다면 배열이기 때문에 사용하였다.

jsonarray에 String으로 된 json 을 담아 파싱한다.

그 다음 아래와 같은 서비스를 호출하고 이 서비스는 @Mapper로 선언 되어있기 때문에 mapper 파일을 만들어 준다.

package com.example.demo.mapper;


import org.apache.ibatis.annotations.Mapper;

import com.example.demo.vo.MartListVO;

@Mapper
public interface MarketListMapper {

	int insertMarketList(MartListVO vo);
	
	int initMarketList();
}

mapper.xml

<?xml version="1.0" encoding="UTF-8"?>

<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
        "http://mybatis.org/dtd/mybatis-3-mapper.dtd">

<mapper namespace="com.example.demo.mapper.MarketListMapper">
    
    <insert id="insertMarketList" parameterType="MartListVO" >
		INSERT INTO `shoppingMall`.`TB_MR_LIST`
		(`MR_CD`,
		`KOR_NM`,
		`ENG_NM`,
		`SYS_DT`)
		VALUES
		(#{mr_cd},
		#{kor_nm},
		#{eng_nm},
		sysdate())	
    </insert>

	<delete id="initMarketList">
		TRUNCATE TB_MR_LIST;
	</delete>
</mapper>

0개의 댓글