Notice
Recent Posts
Recent Comments
Link
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | |||
5 | 6 | 7 | 8 | 9 | 10 | 11 |
12 | 13 | 14 | 15 | 16 | 17 | 18 |
19 | 20 | 21 | 22 | 23 | 24 | 25 |
26 | 27 | 28 | 29 | 30 | 31 |
Tags
- MYSQL
- @jsonproperty
- 데이터베이스
- docker
- 쇼트유알엘
- Kafka
- 스파르타코딩클럽
- emqx
- java
- 개인프로젝트
- 스프링의 정석
- 생성자 주입
- JavaScript
- 남궁성과 끝까지 간다
- JWT
- Spring Security
- 시큐리티
- 프로그래머스
- 항해99
- 패스트캠퍼스
- visualvm
- 스웨거
- Spring
- DB
- 웹개발
- WEB SOCKET
- AWS
- EC2
- CentOS
- 카프카
Archives
- Today
- Total
Nellie's Blog
[TIL-230226일] 프로젝트 ControllerAdvice ,interceptor 본문
728x90
배운점 및 느낀점
1. Server Exception 처리
package com.winterfoodies.controller;
import com.winterfoodies.dto.Sales;
import com.winterfoodies.exception.SalesInternalServerException;
import com.winterfoodies.exception.SalesRequestBodyException;
import com.winterfoodies.interceptor.LogComponent;
import com.winterfoodies.mapper.SalesMapper;
import com.winterfoodies.service.SalesService;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.validation.BindingResult;
import org.springframework.web.bind.annotation.*;
import javax.validation.Valid;
import java.util.*;
// 2023-02-26
//1. Server Exception 처리
//2. ControllerAdvice - exception을 모두 모았다.
//3. log를 남겨보자 - interceptor
@RestController
@Slf4j //로그 남길 수 있는 어노테이션
@RequiredArgsConstructor
@RequestMapping("/sales")
public class SalesController {
private final SalesService salesService;
private final LogComponent logComponent;
//1. 요청이 들어옵니다.
@PostMapping("")
public Integer insertSales(@RequestBody @Valid Sales sales, BindingResult bindingResult){
//2. @Valid라고 선언한 변수에 @NotNull을 만족하지 못하는 데이터가 있는경우 ex) store_id : "";
//아래 이프절에 걸리게 된다.
if(bindingResult.hasErrors()){
//3. 익센션을 던진다.
throw new SalesRequestBodyException("세일즈 누락 데이터 확인 요망",
HttpStatus.BAD_REQUEST);
}
//1.로그를 남긴다.
logComponent.logForSales(sales);
//1. 인서트를 한다.
try {
salesService.insertSales(sales); //DB에 데이터를 넣어! 근데 이때 , DB가 꺼져있는거야!
}catch (Exception e){
}
return 1;
}
@GetMapping("/month/{storeId}")
public Long getMonthSalesByStoreId(@PathVariable Long storeId){
Long salesTotalForMonth = salesService.getMonthSalesMyStoreId(storeId);
return salesTotalForMonth;
}
@GetMapping("/total/{storeId}")
public List<Sales> getAllSalesByStoreId(@PathVariable Long storeId){
Optional<List<Sales>> optionalSalesList = salesService.getAllSalesByStoreId(storeId);
if(optionalSalesList.isPresent()){
return optionalSalesList.get();
}else{
return Collections.emptyList();
}
}
//TO-BE 더 깔끔한 설계를 위해, 익셉션핸들러들을 모두 SalesControllerAdvice에 모아둔다.
/**
//클라이언트 - 요청한 사람의 요청이 잘 못 되었을 경우
//4. 위에 컨트롤러에 선언되어 있는 함수에서 익셉션(SalesRequestBodyException.class) 을 던지면 이짜식이 받는다.
//5. 파라미터로 위에서 던진 SalesRequestBodyException이 들어와진다.
@ExceptionHandler(SalesRequestBodyException.class)
public ResponseEntity<Map<String,String>> salesRequestBodyExceptionHandler(SalesRequestBodyException salesRequestBodyException){
//6. 해당 익셉션으로 데이터를 만든다.
Map<String,String> exceptionBox = Collections.singletonMap("message", salesRequestBodyException.getMessage());
return ResponseEntity.status(salesRequestBodyException.getStatus()).body(exceptionBox);
//7. 호출한 대상에게, 익셉션 박스를 던져준다.
}
//우리의 서버가 잘 못 되었을 경우
//서비스상에서 던져진 익셉션을 잡아서, 처리해주는 익셉션 핸들러입니다.
@ExceptionHandler(SalesInternalServerException.class)
public ResponseEntity<Map<String,String>> salesInternalServerExceptionHandler(SalesInternalServerException salesInternalServerException){
Map<String,String> exceptionBox = Collections.singletonMap("message", salesInternalServerException.getMessage());
return ResponseEntity.status(salesInternalServerException.getStatus()).body(exceptionBox);
}
**/
}
2. ControllerAdvice - exception을 모두 모으기
package com.winterfoodies.controller;
import com.winterfoodies.exception.SalesInternalServerException;
import com.winterfoodies.exception.SalesRequestBodyException;
import com.winterfoodies.interceptor.LogComponent;
import lombok.RequiredArgsConstructor;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.RestControllerAdvice;
import java.util.Collections;
import java.util.Map;
@RestControllerAdvice
@RequiredArgsConstructor
public class SalesControllerAdvice {
private final LogComponent logComponent;
//클라이언트 - 요청한 사람의 요청이 잘 못 되었을 경우
//4. 위에 컨트롤러에 선언되어 있는 함수에서 익셉션(SalesRequestBodyException.class) 을 던지면 이짜식이 받는다.
//5. 파라미터로 위에서 던진 SalesRequestBodyException이 들어와진다.
@ExceptionHandler(SalesRequestBodyException.class)
public ResponseEntity<Map<String,String>> salesRequestBodyExceptionHandler(SalesRequestBodyException salesRequestBodyException){
logComponent.logForSalesRequestBodyException(salesRequestBodyException);
//6. 해당 익셉션으로 데이터를 만든다.
Map<String,String> exceptionBox = Collections.singletonMap("message", salesRequestBodyException.getMessage());
return ResponseEntity.status(salesRequestBodyException.getStatus()).body(exceptionBox);
//7. 호출한 대상에게, 익셉션 박스를 던져준다.
}
//우리의 서버가 잘 못 되었을 경우
//서비스상에서 던져진 익셉션을 잡아서, 처리해주는 익셉션 핸들러입니다.
@ExceptionHandler(SalesInternalServerException.class)
public ResponseEntity<Map<String,String>> salesInternalServerExceptionHandler(SalesInternalServerException salesInternalServerException){
logComponent.logForSalesInternalServerException(salesInternalServerException);
Map<String,String> exceptionBox = Collections.singletonMap("message", salesInternalServerException.getMessage());
return ResponseEntity.status(salesInternalServerException.getStatus()).body(exceptionBox);
}
}
3. log를 남겨보자 - interceptor
package com.winterfoodies.interceptor;
import com.winterfoodies.dto.Sales;
import com.winterfoodies.exception.SalesInternalServerException;
import com.winterfoodies.exception.SalesRequestBodyException;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;
@Component
@Slf4j
public class LogComponent{
// 로그 출력을 StringBuilder에 담아서, log.info를 찍어준다. 조금 더 깔끔한 코드로!
public void logForSales(Sales sales){
StringBuilder logMessageBuilder = new StringBuilder();
logMessageBuilder.append("[매출데이터로그]<<<");
logMessageBuilder.append("SALES_ID: " + sales.getSales_id()+ " ");
logMessageBuilder.append("ORDER_AT: " + sales.getOrder_at()+ " ");
logMessageBuilder.append("STORE_ID: " + sales.getStore_id()+ " ");
logMessageBuilder.append("TOTAL_PRC: " + sales.getTotal_price()+ " ");
logMessageBuilder.append("CUSTOMER_ID: " + sales.getCustomer_id()+ " ");
logMessageBuilder.append("PRODUCT_ID: " + sales.getProduct_id()+ " ");
logMessageBuilder.append(">>>");
log.info(logMessageBuilder.toString());
}
public void logForSalesRequestBodyException(SalesRequestBodyException salesRequestBodyException){
StringBuilder logMessageBuilder = new StringBuilder();
logMessageBuilder.append("[SALES_REQUESTBODY_EXCEPTION 로그]<<<");
logMessageBuilder.append("EXCEPTION_MESSAGE: " + salesRequestBodyException.getMessage()+ " ");
logMessageBuilder.append("EXCEPTION_STATUS: " + salesRequestBodyException.getStatus()+ " ");
logMessageBuilder.append(">>>");
log.info(logMessageBuilder.toString());
}
public void logForSalesInternalServerException(SalesInternalServerException salesInternalServerException){
StringBuilder logMessageBuilder = new StringBuilder();
logMessageBuilder.append("[SALES_INTERNAL_SERVER_EXCEPTION 로그]<<<");
logMessageBuilder.append("EXCEPTION_MESSAGE: " + salesInternalServerException.getMessage()+ " ");
logMessageBuilder.append("EXCEPTION_STATUS: " + salesInternalServerException.getStatus()+ " ");
logMessageBuilder.append(">>>");
log.info(logMessageBuilder.toString());
}
}
'회고록' 카테고리의 다른 글
[TIL-230228화] 스프링 입문 - 코드로 배우는 스프링 부트 강의 정리 (0) | 2023.03.01 |
---|---|
[TIL-230227월] 스프링 입문 - 코드로 배우는 스프링 부트 강의 (0) | 2023.02.27 |
[TIL-230224금] 디자인패턴 - 싱글턴, 전략패턴 공부 (0) | 2023.02.25 |
[TIL-230223목] 정처기 실기 공부 및 SQL정리 (0) | 2023.02.23 |
[TIL-230222수] 정처기 실기 공부 및 쿼리공부 (0) | 2023.02.22 |