[01.17] 내일배움캠프[Spring] TIL-55
1. Spring Project
- 내가 맡은 기능:
CutomerService
,SellerService
에 따른 Repository
,Controller
Customer
모든 판매자 보기 - showSellerList
@GetMapping("/sellers")
public ResponseEntity<Page<SellerListResponseDto>> showSellerList(@RequestParam int page){
Page<SellerListResponseDto> sellerList = customerService.showSellerList(page);
HttpHeaders headers = new HttpHeaders();
headers.setContentType(new MediaType("application", "json", StandardCharsets.UTF_8));
return ResponseEntity.status(HttpStatus.CREATED).headers(headers).body(sellerList);
}
@Override
@Transactional(readOnly = true)
public Page<SellerListResponseDto> showSellerList(int page) {
Pageable pageable = PageRequest.of(page,10);
Page<User> sellerList = userRepository.findAllByRoleOrderByIdDesc(UserRoleEnum.SELLER,pageable);
return new PageImpl<>(sellerList.stream().map(SellerListResponseDto::new).collect(Collectors.toList()));
}
- 원래 알았던 Page처리는 오름차순 정렬이나 어떠한 title을 주제로 orderBy할 것인지에 대한 개념 부족 때문에 시도를 못하고 있던 중,
page
,size
만으로 처리가 가능하다는 소식을 듣고 뒤늦게 수정!
- 회원 가입된 User중에서 Role = Seller 인 것을 찾아오는 쿼리
- 근데
Page<User>
-> 했다고 해서 List<>형식을 어떻게 담을 수 있는건가?
-> 코드 따고 들어가보면 Iterator<> 즉 List형식의 표현이 가능하다는 것을 알 수 있음.
구매요청하기 - requestBuyProducts
@PostMapping("/products/{productsId}")
public ResponseEntity requestBuyProducts(@PathVariable long productsId, User user){
String msg = customerService.requestBuyProducts(user.getId(),productsId);
HttpHeaders headers = new HttpHeaders();
headers.setContentType(new MediaType("application", "json", StandardCharsets.UTF_8));
return ResponseEntity.status(HttpStatus.OK).headers(headers).body(new StatusResponseDto(HttpStatus.OK.value(),msg));
}
@Override
@Transactional
public String requestBuyProducts(long userId,long productId) {
if(customerRequestListRepository.findByProductId(productId)!=null){
throw new IllegalArgumentException("이미 구매요청이 걸려있는 상품입니다!");
}else{
Product product = productRepository.findById(productId).orElseThrow(
()->new IllegalArgumentException("구매하고자 하는 상품이 없습니다!")
);
customerRequestListRepository.save(new CustomerRequestList(userId,product.getUserId(),product.getId()));
return "구매요청이 완료되었습니다!";
}
}
@Tranactional
: 아직 정확하게 아는 것은 아니지만, 만약 상품을 조회하거나, 요청 엔티티를 조회하는 도중 오류가 났을 때, save딴의 쿼리까지 안갔으면 좋겠다는 생각에 넣어줬다.
- User 객체를 받는 것은 나중에
SpringSecurity
기 적용되어서 AuthenticaionPrinciple
에서 UserDetails
를 가져올 때를 위해 적어 놓은 것이다.
-> 그 해당 로직에는 인증/인가가 된 User가 필요하다는 뜻!
Seller
내 상품 구매요청자 보기 - showCustomerList
@GetMapping("/customers")
public ResponseEntity<Page<CustomerListResponseDto>> showCustomerList(@RequestParam int page, User user){
Page<CustomerListResponseDto> customerListResponseDtoList = sellerService.showCustomerList(page,user);
HttpHeaders headers = new HttpHeaders();
headers.setContentType(new MediaType("application", "json", StandardCharsets.UTF_8));
return ResponseEntity.status(HttpStatus.OK).headers(headers).body(customerListResponseDtoList);
}
@Override
@Transactional(readOnly = true)
public Page<CustomerListResponseDto> showCustomerList(int page,User user) {
Pageable pageable = PageRequest.of(page,10);
Page<CustomerRequestList> customerList = customerRequestListRepository.findAllBySellerId(user.getId(),pageable);
if(customerList==null){
throw new IllegalArgumentException("판매요청한 구매자가 없습니다!");
}
return new PageImpl<>(customerList.stream().map(CustomerListResponseDto::new).collect(Collectors.toList()));
}
- 어차피 조회 딴 쿼리만 쓰이기 때문에 readOnly = true를 붙여주었다.
- 여기도 마찬가지도 페이징 처리를 시도했다.
- 원래 jpa기본 메서드
findAll(),findById()...
와 같은 메서드는 값이 없을 때의 예외를 OrElseThow()
로 던져서 한줄 표현이 가능한데, 직접 선언한 메서드의 경우에는 따로 Exception처리를 강요하지 않는다. 하지만 예외는 무조건 발생할 수 있기 때문에 일단은 null로 처리를 해놓았다.
- 마찬가지로
SpringSecurity
적용 전 단계라 아직은 User 선언.
구매요청 수락하기 - acceptBuyRequest
@PostMapping("/customers/{customerId}")
public ResponseEntity acceptBuyRequest(@PathVariable long customerId){
String msg = sellerService.acceptBuyRequest(customerId);
HttpHeaders headers = new HttpHeaders();
headers.setContentType(new MediaType("application", "json", StandardCharsets.UTF_8));
return ResponseEntity.status(HttpStatus.OK).headers(headers).body(new StatusResponseDto(HttpStatus.OK.value(), msg));
}
@Override
@Transactional
public String acceptBuyRequest(long customerId) {
CustomerRequestList customerRequestList = customerRequestListRepository.findByUserId(customerId);
if(customerRequestList==null){
throw new IllegalArgumentException("해당 사용자의 판매요청이 없습니다!");
}
customerRequestList.acceptBySeller();
return "해당 사용자의 판매요청이 수락되었습니다!";
}
- API설계에서는 사실
@PathVariable
로 cutomerId
를 따로 받지 않았는데, 코드를 짜다보니, 구매를 요청한 cutomerId
가 필요했지만 현재 코드에서 끌어올 수 있는 방법이 업었다, 또한 다른 웹페이지도 마찬가지로, UI상에서 그 cutomer의 요청을 클릭한다면 그 cutomerId가 넘어갈 것임을 믿어 의심치 않는다.
- 코드가 굉장히 간단하고 어 그럼 다른 권한없는 사람도 그냥 URL요청으로 Controller타고 이거 로직 터트릴 수 있는거 아닌가? -> 나중에
@Secured()
로 막아줄 것!
-> AccessDeniedException
내 판매상품 보기 - showMyProducts
@GetMapping("/products/list")
public ResponseEntity<Page<ProductResponseDto>> showMyProducts(@RequestParam int page,User user){
Page<ProductResponseDto> products = sellerService.showMyProducts(page,user);
HttpHeaders headers = new HttpHeaders();
headers.setContentType(new MediaType("application", "json", StandardCharsets.UTF_8));
return ResponseEntity.status(HttpStatus.OK).headers(headers).body(products);
}
@Override
@Transactional(readOnly = true)
public Page<ProductResponseDto> showMyProducts(int page,User user) {
Pageable pageable = PageRequest.of(page,10);
Page<Product> products = productRepository.findAllByUserId(user.getId(),pageable);
if(products==null){
throw new IllegalArgumentException("내 판매상품 내역이 없습니다!");
}
return new PageImpl<>(products.stream().map(ProductResponseDto::new).collect(Collectors.toList()));
}
- 마찬가지로 아직 SpringSecurity 적용 전!
- Page처리 시도!