![[인프런워밍업클럽 3기 BE] 3주차 발자국](https://cdn.inflearn.com/public/files/blogs/b7b894f1-9458-4e21-b80a-7fc8e48ce361/발자국.png)
[인프런워밍업클럽 3기 BE] 3주차 발자국
29일 전
1. 강의
1.1 학습내용
@RestControllerAdvice
Spring에서 예외 처리를 전역적으로 관리할 수 있도록 도와주는 어노테이션이다.
JSON 형태로 응답을 반환하는 데 최적화 되어 있다.
@ExceptionHandler
와 함께 사용하여 세부적인 특정 예외 유형 처리가 가능하다.@ExceptionHandler
는 컨트롤러 내부에서 사용하면 개별 처리,@RestControllerAdvice
와 함께 사용하면 전역 예외 처리 가능하다.여러 개의 예외를 한 메서드에서 처리 가능하다.
@RestControllerAdvice class AdminApiControllerAdvice { val log = LoggerFactory.getLogger(AdminApiControllerAdvice::class.java) @ExceptionHandler fun handleException(e: AdminException):ResponseEntity<String> { log.info(e.message , e) return ResponseEntity.status(e.httpStatus).body(e.message) } @ExceptionHandler fun handleException(e: MethodArgumentNotValidException):ResponseEntity<String> { log.info(e.message , e) val fieldError = e.bindingResult.fieldErrors[0] val message = "[${fieldError.field} ${fieldError.defaultMessage}]" return ResponseEntity.badRequest().body(message) } }
1.2 느낀 점
템플릿 라이센스 문제로 이번주 봐야될 강의가 줄어들어 미션에 좀 더 집중 할 수 있었다.
2. 미션
2.1. 조회 REST API 만들기
2.2. 삽입, 수정, 삭제 API 만들기
테스트 케이스를 만들면서 상품, 주문 정보가 없는 경우 사용자 정의 에러를 만들어서 던지게 변경하였다.
class OrderNotFoundException(val orderNo: Long) : CustomException("해당 주문정보가 없습니다. [주문번호 : $orderNo]")
class ProductNotFoundException(val productCd: Long) : CustomException("해당 상품코드가 없습니다. [상품코드 : $productCd]")
주문 등록
@Transactional
fun create(requestDTO: RequestCreateDTO): ResponseEntity<ResponseDTO> {
// 주문 마스터 생성
val orderHeader = Order(orderSts = OrderSts.PAYMENT_COMPLETED.code)
orderRepository.save(orderHeader)
// 주문 상세 생성
requestDTO.items.forEach { item ->
val product = productRepository.findById(item.productCd).orElseThrow {
ProductNotFoundException(item.productCd) // 상품 코드가 없을 경우 예외 던지기
}
val orderDetail = OrderDetail(
order = orderHeader,
product = product,
price = item.price,
qty = item.qty,
memo = item.memo
)
orderDetailRepository.save(orderDetail)
}
val response = ResponseDTO(
code = 200,
msg = "주문 등록 성공",
orderNo = orderHeader.orderNo,
orderSts = orderHeader.orderSts
)
return ResponseEntity.status(HttpStatus.OK).body(response)
}
주문 수정
@Transactional
fun update(orderNo: Long, requestDTO: RequestUpdateDTO): ResponseEntity<ResponseDTO> {
// 주문 마스터
val orderHeader = orderRepository.findById(orderNo).orElseThrow {
OrderNotFoundException(orderNo) // 주문 정보가 없을 경우 예외 던지기
}
if ("60".equals(orderHeader.orderSts)) {
val errorRes = ResponseDTO(
code = 400,
msg = "배송완료 상태는 수정 할 수 없습니다. [주문번호 : ${orderNo}]",
orderNo = null,
orderSts = null
)
return ResponseEntity.status(HttpStatus.BAD_REQUEST).body(errorRes)
}
if (requestDTO.orderSts > 0 ) {
// 주문 상태가 유효한 코드인지 확인하고 적용
val orderSts = OrderSts.values().find { it.code == requestDTO.orderSts } ?: throw ApiException("유효하지 않은 주문 상태 코드입니다. [주문상태 : ${requestDTO.orderSts}]")
// 주문 마스터 업데이트
orderHeader.orderSts = orderSts.code // code 값으로 업데이트
orderRepository.save(orderHeader) // 주문 상태를 업데이트
}
// 주문 상세
val orderDetail = orderDetailRepository.findByOrderNo(orderNo)
requestDTO.items.forEach { item ->
val product = productRepository.findById(item.productCd).orElseThrow {
ProductNotFoundException(item.productCd) // 상품 코드가 없을 경우 예외 던지기
}
// 주문 상세 업데이트
val updateOrderDetail = orderDetail.find { it.product == product }
if (updateOrderDetail != null) {
updateOrderDetail.price = item.price
updateOrderDetail.qty = item.qty
updateOrderDetail.memo = item.memo
orderDetailRepository.save(updateOrderDetail) // 업데이트
}
}
// 응답 반환
val response = ResponseDTO(
code = 200,
msg = "주문 수정 성공",
orderNo = orderNo,
orderSts = orderHeader.orderSts
)
return ResponseEntity.status(HttpStatus.OK).body(response)
}
주문 삭제
@Transactional
fun delete(orderNo: Long): ResponseEntity<ResponseDTO> {
val orderHeader = orderRepository.findById(orderNo).orElseThrow {
OrderNotFoundException(orderNo) // 주문 정보가 없을 경우 예외 던지기
}
val orderSts = orderHeader.orderSts
if ("60".equals(orderSts)) {
val errorRes = ResponseDTO(
code = 400,
msg = "배송완료 상태는 삭제 할 수 없습니다. [주문번호 : ${orderNo}]",
orderNo = null,
orderSts = null
)
return ResponseEntity.status(HttpStatus.BAD_REQUEST).body(errorRes)
}
// 주문 마스터
orderHeader.delYn = "Y"
orderRepository.save(orderHeader)
// 주문 상세
val orderDetailList = orderDetailRepository.findByOrderNo(orderNo)
orderDetailList.forEach { it.delYn = "Y" } // delYn 필드 값을 "Y"로 변경
orderDetailRepository.saveAll(orderDetailList) // 변경된 리스트를 저장
val response = ResponseDTO(
code = 200,
msg = "주문 삭제 성공",
orderNo = orderNo,
orderSts = null
)
return ResponseEntity.status(HttpStatus.OK).body(response)
}
2.3. 느낀 점
조회 API 만들기 미션은 제출하지 못했고 삽입, 수정, 삭제 API 만들기 미션은 겨우 제출하였다.
생각보다 내가 원하는 기능은 구현하는게 빠르게 되지 않아서 많이 검색해보았다.
개발하고 나서 사용하지 않는 테이블과 컬럼들을 정리하였다. 초기 ERD와 좀 다르게 되어서 ERD도 다시 수정하였다.