Spring(기초)-4주차-5
1. 스케줄러 만들기
- 매일 새벽 1시에 관심 상품 목록 제목으로 검색해서, 최저가 정보를 업데이트하는 스케줄러를 생성
Scheduler 클래스
- Scheduler.java (src > main > java > com.sparta.week04 > utils)
package com.sparta.week04.utils;
import com.sparta.week04.models.ItemDto;
import com.sparta.week04.models.Product;
import com.sparta.week04.models.ProductRepository;
import com.sparta.week04.service.ProductService;
import lombok.RequiredArgsConstructor;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;
import java.util.List;
import java.util.concurrent.TimeUnit;
@RequiredArgsConstructor // final 멤버 변수를 자동으로 생성합니다.
@Component // 스프링이 필요 시 자동으로 생성하는 클래스 목록에 추가합니다.
public class Scheduler {
private final ProductRepository productRepository;
private final ProductService productService;
private final NaverShopSearch naverShopSearch;
// 초, 분, 시, 일, 월, 주 순서
@Scheduled(cron = "0 0 1 * * *") // 정확히 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);
}
}
}
ProductService 클래스 개선
package com.sparta.week04.service;
import com.sparta.week04.models.ItemDto;
import com.sparta.week04.models.Product;
import com.sparta.week04.models.ProductMypriceRequestDto;
import com.sparta.week04.models.ProductRepository;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;
import javax.transaction.Transactional;
@RequiredArgsConstructor
@Service
public class ProductService {
private final ProductRepository productRepository;
@Transactional
public Long update(Long id, ProductMypriceRequestDto requestDto) {
Product product = productRepository.findById(id).orElseThrow(
() -> new NullPointerException("해당 아이디가 존재하지 않습니다.")
);
product.update(requestDto);
return id;
}
////////// 추가 //////////
@Transactional
public Long updateBySearch(Long id, ItemDto itemDto){
Product product = productRepository.findById(id).orElseThrow(
() -> new IllegalArgumentException("아이디가 존재하지 않습니다")
);
product.updateByItemDto(itemDto);
return id;
}
/////////////////////////
}
Applicatioon 개선
package com.sparta.week04;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.data.jpa.repository.config.EnableJpaAuditing;
import org.springframework.scheduling.annotation.EnableScheduling;
@EnableScheduling // 추가: 스프링 부트에서 스케줄러가 작동하게 합니다.
@EnableJpaAuditing // 시간 자동 변경이 가능하도록 합니다.
@SpringBootApplication // 스프링 부트임을 선언합니다.
public class Week04Application {
public static void main(String[] args) {
SpringApplication.run(Week04Application.class, args);
}
}
2. 최저가 변경 만들기
setMyprice 만들기
function setMyprice() {
/**
* 숙제! myprice 값 설정하기.
* 1. id가 myprice 인 input 태그에서 값을 가져온다.
* 2. 만약 값을 입력하지 않았으면 alert를 띄우고 중단한다.
* 3. PUT /api/product/${targetId} 에 data를 전달한다.
* 주의) contentType: "application/json",
* data: JSON.stringify({myprice: myprice}),
* 빠뜨리지 말 것!
* 4. 모달을 종료한다. $('#container').removeClass('active');
* 5, 성공적으로 등록되었음을 알리는 alert를 띄운다.
* 6. 창을 새로고침한다. window.location.reload();
*/
// 1. id가 myprice 인 input 태그에서 값을 가져온다.
let myprice = $('#myprice').val();
// 2. 만약 값을 입력하지 않았으면 alert를 띄우고 중단한다.
if (myprice == '') {
alert('올바른 가격을 입력해주세요');
return;
}
// 3. PUT /api/product/${targetId} 에 data를 전달한다.
$.ajax({
type: "PUT",
url: `/api/products/${targetId}`,
contentType: "application/json",
data: JSON.stringify({myprice: myprice}),
success: function (response) {
// 4. 모달을 종료한다. $('#container').removeClass('active');
$('#container').removeClass('active');
// 5. 성공적으로 등록되었음을 알리는 alert를 띄운다.
alert('성공적으로 등록되었습니다.');
// 6. 창을 새로고침한다. window.location.reload();
window.location.reload();
}
})
}
ProductRestController 개선
package com.sparta.week04.controller;
import com.sparta.week04.models.Product;
import com.sparta.week04.models.ProductMypriceRequestDto;
import com.sparta.week04.models.ProductRepository;
import com.sparta.week04.models.ProductRequestDto;
import com.sparta.week04.service.ProductService;
import lombok.RequiredArgsConstructor;
import org.springframework.web.bind.annotation.*;
import java.util.List;
@RequiredArgsConstructor // final로 선언된 멤버 변수를 자동으로 생성합니다.
@RestController // JSON으로 데이터를 주고받음을 선언합니다.
public class ProductRestController {
private final ProductRepository productRepository;
private final ProductService productService; // 추가
// 등록된 전체 상품 목록 조회
@GetMapping("/api/products")
public List<Product> getProducts() {
return productRepository.findAll();
}
// 신규 상품 등록
@PostMapping("/api/products")
public Product createProduct(@RequestBody ProductRequestDto requestDto) {
Product product = new Product(requestDto);
productRepository.save(product);
return product;
}
////////// 추가 //////////
// 설정 가격 변경
@PutMapping("/api/products/{id}")
public Long updateProduct(@PathVariable Long id, @RequestBody ProductMypriceRequestDto requestDto) {
return productService.update(id, requestDto);
}
////////////////////////
}
Author And Source
이 문제에 관하여(Spring(기초)-4주차-5), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다
https://velog.io/@kju190920/Spring기초-4주차-5
저자 귀속: 원작자 정보가 원작자 URL에 포함되어 있으며 저작권은 원작자 소유입니다.
우수한 개발자 콘텐츠 발견에 전념
(Collection and Share based on the CC Protocol.)
package com.sparta.week04.utils;
import com.sparta.week04.models.ItemDto;
import com.sparta.week04.models.Product;
import com.sparta.week04.models.ProductRepository;
import com.sparta.week04.service.ProductService;
import lombok.RequiredArgsConstructor;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;
import java.util.List;
import java.util.concurrent.TimeUnit;
@RequiredArgsConstructor // final 멤버 변수를 자동으로 생성합니다.
@Component // 스프링이 필요 시 자동으로 생성하는 클래스 목록에 추가합니다.
public class Scheduler {
private final ProductRepository productRepository;
private final ProductService productService;
private final NaverShopSearch naverShopSearch;
// 초, 분, 시, 일, 월, 주 순서
@Scheduled(cron = "0 0 1 * * *") // 정확히 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);
}
}
}
package com.sparta.week04.service;
import com.sparta.week04.models.ItemDto;
import com.sparta.week04.models.Product;
import com.sparta.week04.models.ProductMypriceRequestDto;
import com.sparta.week04.models.ProductRepository;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;
import javax.transaction.Transactional;
@RequiredArgsConstructor
@Service
public class ProductService {
private final ProductRepository productRepository;
@Transactional
public Long update(Long id, ProductMypriceRequestDto requestDto) {
Product product = productRepository.findById(id).orElseThrow(
() -> new NullPointerException("해당 아이디가 존재하지 않습니다.")
);
product.update(requestDto);
return id;
}
////////// 추가 //////////
@Transactional
public Long updateBySearch(Long id, ItemDto itemDto){
Product product = productRepository.findById(id).orElseThrow(
() -> new IllegalArgumentException("아이디가 존재하지 않습니다")
);
product.updateByItemDto(itemDto);
return id;
}
/////////////////////////
}
package com.sparta.week04;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.data.jpa.repository.config.EnableJpaAuditing;
import org.springframework.scheduling.annotation.EnableScheduling;
@EnableScheduling // 추가: 스프링 부트에서 스케줄러가 작동하게 합니다.
@EnableJpaAuditing // 시간 자동 변경이 가능하도록 합니다.
@SpringBootApplication // 스프링 부트임을 선언합니다.
public class Week04Application {
public static void main(String[] args) {
SpringApplication.run(Week04Application.class, args);
}
}
setMyprice 만들기
function setMyprice() {
/**
* 숙제! myprice 값 설정하기.
* 1. id가 myprice 인 input 태그에서 값을 가져온다.
* 2. 만약 값을 입력하지 않았으면 alert를 띄우고 중단한다.
* 3. PUT /api/product/${targetId} 에 data를 전달한다.
* 주의) contentType: "application/json",
* data: JSON.stringify({myprice: myprice}),
* 빠뜨리지 말 것!
* 4. 모달을 종료한다. $('#container').removeClass('active');
* 5, 성공적으로 등록되었음을 알리는 alert를 띄운다.
* 6. 창을 새로고침한다. window.location.reload();
*/
// 1. id가 myprice 인 input 태그에서 값을 가져온다.
let myprice = $('#myprice').val();
// 2. 만약 값을 입력하지 않았으면 alert를 띄우고 중단한다.
if (myprice == '') {
alert('올바른 가격을 입력해주세요');
return;
}
// 3. PUT /api/product/${targetId} 에 data를 전달한다.
$.ajax({
type: "PUT",
url: `/api/products/${targetId}`,
contentType: "application/json",
data: JSON.stringify({myprice: myprice}),
success: function (response) {
// 4. 모달을 종료한다. $('#container').removeClass('active');
$('#container').removeClass('active');
// 5. 성공적으로 등록되었음을 알리는 alert를 띄운다.
alert('성공적으로 등록되었습니다.');
// 6. 창을 새로고침한다. window.location.reload();
window.location.reload();
}
})
}
ProductRestController 개선
package com.sparta.week04.controller;
import com.sparta.week04.models.Product;
import com.sparta.week04.models.ProductMypriceRequestDto;
import com.sparta.week04.models.ProductRepository;
import com.sparta.week04.models.ProductRequestDto;
import com.sparta.week04.service.ProductService;
import lombok.RequiredArgsConstructor;
import org.springframework.web.bind.annotation.*;
import java.util.List;
@RequiredArgsConstructor // final로 선언된 멤버 변수를 자동으로 생성합니다.
@RestController // JSON으로 데이터를 주고받음을 선언합니다.
public class ProductRestController {
private final ProductRepository productRepository;
private final ProductService productService; // 추가
// 등록된 전체 상품 목록 조회
@GetMapping("/api/products")
public List<Product> getProducts() {
return productRepository.findAll();
}
// 신규 상품 등록
@PostMapping("/api/products")
public Product createProduct(@RequestBody ProductRequestDto requestDto) {
Product product = new Product(requestDto);
productRepository.save(product);
return product;
}
////////// 추가 //////////
// 설정 가격 변경
@PutMapping("/api/products/{id}")
public Long updateProduct(@PathVariable Long id, @RequestBody ProductMypriceRequestDto requestDto) {
return productService.update(id, requestDto);
}
////////////////////////
}
Author And Source
이 문제에 관하여(Spring(기초)-4주차-5), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://velog.io/@kju190920/Spring기초-4주차-5저자 귀속: 원작자 정보가 원작자 URL에 포함되어 있으며 저작권은 원작자 소유입니다.
우수한 개발자 콘텐츠 발견에 전념 (Collection and Share based on the CC Protocol.)