public class NaverShopSearch {
public String search() {
RestTemplate rest = new RestTemplate();
HttpHeaders headers = new HttpHeaders();
headers.add("X-Naver-Client-Id", {클라이언트 아이디});
headers.add("X-Naver-Client-Secret", {클라이언트 시크릿});
String body = "";
HttpEntity<String> requestEntity = new HttpEntity<String>(body, headers);
ResponseEntity<String> responseEntity = rest.exchange("https://openapi.naver.com/v1/search/shop.json?query=iphone", HttpMethod.GET, requestEntity, String.class);
HttpStatus httpStatus = responseEntity.getStatusCode();
int status = httpStatus.value();
String response = responseEntity.getBody();
System.out.println("Response status: " + status);
System.out.println(response);
return response;
}
public static void main(String[] args) {
NaverShopSearch naverShopSearch = new NaverShopSearch();
naverShopSearch.search();
}
}
3계층 설계하기
Timestamped
@Getter // get 함수를 자동 생성합니다. @MappedSuperclass // 멤버 변수가 컬럼이 되도록 합니다. @EntityListeners(AuditingEntityListener.class) // 변경되었을 때 자동으로 기록합니다. public abstract class Timestamped { @CreatedDate // 최초 생성 시점 private LocalDateTime createdAt; @LastModifiedDate // 마지막 변경 시점 private LocalDateTime modifiedAt; }
- Week04Application에 @EnableJpaAuditing을 추가해준다. 이로써 시간 자동 변경이 가능하도록 한다.
Product
@Getter // get 함수를 일괄적으로 만들어줍니다. @NoArgsConstructor // 기본 생성자를 만들어줍니다. @Entity // DB 테이블 역할을 합니다. public class Product extends Timestamped{ @GeneratedValue(strategy = GenerationType.AUTO) // ID가 자동으로 생성 및 증가합니다. @Id private Long id; @Column(nullable = false) // 반드시 값을 가지도록 합니다. private String title; @Column(nullable = false) private String image; @Column(nullable = false) private String link; @Column(nullable = false) private int lprice; @Column(nullable = false) private int myprice; }
ProductRepository(interface)
public interface ProductRepository extends JpaRepository<Product, Long> { }
ProductRestController
@RequiredArgsConstructor // final로 선언된 멤버 변수를 자동으로 생성합니다. @RestController // JSON으로 데이터를 주고받음을 선언합니다. public class ProductRestController { private final ProductRepository productRepository; // 등록된 전체 상품 목록 조회 @GetMapping("/api/products") public List<Product> getProducts() { return productRepository.findAll(); } }
ProductRequestDto
@Getter public class ProductRequestDto { private String title; private String link; private String image; private int lprice; }
ProductMypriceRequestDto
@Getter public class ProductMypriceRequestDto { private int myprice; }
ProductService
@RequiredArgsConstructor // final로 선언된 멤버 변수를 자동으로 생성합니다. @Service // 서비스임을 선언합니다. public class ProductService { private final ProductRepository productRepository; @Transactional // 메소드 동작이 SQL 쿼리문임을 선언합니다. public Long update(Long id, ProductMypriceRequestDto requestDto) { Product product = productRepository.findById(id).orElseThrow( () -> new NullPointerException("해당 아이디가 존재하지 않습니다.") ); product.update(requestDto); return id; } }
org.json 패키지 설치하기(외부 라이브러리)
cf) org.json: JSON을 자바에서 다루기 위해, JSONObject/JSONArray 클래스가 필요하다. 이를 사용하기 위한 라이브러리이다.
NaverShopSearch 컴포넌트 등록: 스프링이 자동으로 필요한 클래스를 필요한 곳에 생성하기 위해, 자동으로 생성할 클래스 목록에 등록하는 간단한 방법이 컴포넌트 등록이다.
이와 같이 컴포넌트 등록을 해야 나중에 private final을 사용하기 위한 @RequiredArgsConstructor에서 NaverShopSearch를 찾을 수 있다.
Scheduler
@RequiredArgsConstructor // final 멤버 변수를 자동으로 생성합니다. @Component // 스프링이 필요 시 자동으로 생성하는 클래스 목록에 추가합니다. public class Scheduler { private final ProductRepository productRepository; private final ProductService productService; private final NaverShopSearch naverShopSearch; // 초, 분, 시, 일, 월, 주 순서 @Scheduled(cron = "0 0 1 * * *") public void updatePrice() throws InterruptedException { System.out.println("가격 업데이트 실행"); // 저장된 모든 관심상품을 조회합니다. List<Product> productList = productRepository.findAll(); for (int i=0; i<productList.size(); i++) { // 1초에 한 상품 씩 조회합니다 (Naver 제한) TimeUnit.SECONDS.sleep(1); // i 번째 관심 상품을 꺼냅니다. Product p = productList.get(i); // i 번째 관심 상품의 제목으로 검색을 실행합니다. String title = p.getTitle(); String resultString = naverShopSearch.search(title); // i 번째 관심 상품의 검색 결과 목록 중에서 첫 번째 결과를 꺼냅니다. List<ItemDto> itemDtoList = naverShopSearch.fromJSONtoItems(resultString); ItemDto itemDto = itemDtoList.get(0); // i 번째 관심 상품 정보를 업데이트합니다. Long id = p.getId(); productService.updateBySearch(id, itemDto); } } }
- 추가적으로 Week04Application에 @EnableScheduling을 붙여야 정상적으로 동작하다.