Controller - RestController의 차이
Controller는 응닶값이 기본적으로 HTML을 주도록 되어있음 -> 이는 백엔드와 프론트엔드의 차이가 없었을 때 나온 것으로 풀스택 개발시 활용되어왔음. 데이터를 뷰에 넘김
RestController는 응답값으로 Rest API요청에 대한 응답(주로 JSON으로 응답 넘김)으로 사용됨. 데이터만 넘김
GetMapping
GetMapping에서 @RequestParam과 PathVariable의 사용 시기
PathVarible
특정 객체의 id값만을 가지고 단일 객체로 가져오려고 할 경우
@GetMapping("/order/{orderId}")
public String getSomething(@PathVariable String orderId) {
log.info("Get some order");
return "orderId :" + orderId + ", " + "orderAmount : 1000";
}
RequestParam
가져오려고하는데 쿼리 스트링으로 여러개의 값을 넘겨야 할 때 예를 들어 SearchKeyword로 페이지의 값을 넘기거나 다중의 값을 넘길 때 사용
@GetMapping("/order")
public String getSomething2(@RequestParam String orderId,
@RequestParam Integer orderAmount) {
log.info("@RequestParam = {}, orderAmount = {}", orderId, orderAmount);
return "orderId :" + orderId + ", " + "orderAmount :" + orderAmount;
}
@RequiredParam의 옵션 required를 통해 필수로 필요한 값인지 아닌지 알려줄 수 있음
@RequestBody, @RequestHeader
@RequestBody
HttpBody의 정보를 편리하게 받을 수 있음 -> 주로 사용하는 메시지 포맷은 JSON, 데이터의 양이 많을 때 URL로 쿼리 스트링을 넘기는 데는 한계가 있음.RequestBody는 주로 JSON 데이터를 자바 객체로 변환함.
@RequestHeader
HttpHeader의 정보를 편리하게 받을 수 있음
@PostMapping("/create")
public String createOrder(@RequestBody CreateOrderRequest orderRequest,
@RequestHeader String userAccountId) {
log.info("Create order = {}, userAccountId = {}",
orderRequest, userAccountId);
return "order created -> orderId :" + orderRequest.getOrderId() +
", orderAmount" + orderRequest.getOrderAmount();
}
Header를 통해 HTTP의 Header정보를 편하게 넘긿 수 있다. 그리고 인자로
@RequestHeader String userAccountId 부분을 통해서 userAccountId와 같은 민감한 값들은 Body가 아닌 Header로 받아서 숨길 수 있다.
ExceptionHandler
- 컨트롤러 기반 예외 처리
- Http Status Code를 변경하는 방법
- @ResponseStatus
- ResponseEntity 활용
- 예외 처리 우선 순위
- 해당 Exception이 정확히 지정된 Handler
- 해당 Exception의 부모 예외 Handler
- 이도 저도 아니면 그냥 Exception(모든 예외의 부모)
@GetMapping("/order/{orderId}")
public String getSomething(@PathVariable String orderId) {
if (orderId.equals("500")) {
throw new WebSampleException(ErrorCode.TOO_BIG_ID_ERROR,"500 is not valid");
}
log.info("Get some order");
return "orderId :" + orderId + ", " + "orderAmount : 1000";
}
@ExceptionHandler(WebSampleException.class)
public ResponseEntity<ErrorResponse> handleIllegalAccessException(WebSampleException e) {
log.error("WebSampleException is occurred", e);
return ResponseEntity.status(HttpStatus.BAD_REQUEST)
.header("newHeader", "Some Value")
.body(new ErrorResponse("ID의 값이 너무 커",
e.getErrorCode()));
}
@AllArgsConstructor
@ToString
@Getter
public class WebSampleException extends RuntimeException {
private ErrorCode errorCode;
private String message;
}
public enum ErrorCode {
TOO_BIG_ID_ERROR, TOO_SMALL_ID_ERROR
}
![[Pasted image 20240917164809.png]]
@RestControllerAdvice
- 어플리케이션의 전역적 예외 처리
- @ControllerAdvice와의 차이
- ControllerAdivce는 기본적으로 View 로 응답하는 방식
- RestControllerAdvice : REST API용으로 객체를 응답하는 방식(주로 JSON)
RestControllerAdivce는 현재 스프링 백엔드 개발에서 가장 많이 활용되는 기술이다.
일관성 있는 예외처리
현재의 에러 메시지
{
"timestamp": "2024-09-23T14:31:40.507+00:00",
"status": 500,
"error": "Internal Server Error",
"path": "/transaction/cancel"
}
실제 에러는 CANCEL_MUST_FULLY 에러이다.
해당 에러로는 정확한 에러 원인을 Client에서 확인하기 어렵다.
에러응답을 어떻게 줘야 Client(서버,FE, 앱)에서 처리하기 편할 까??
- Http status code를 사용하는 방법(200 Ok, 404 Not Found)
- 별도의 status code를 사용하는 방법 (0000 성공, -1001, -1002)
- ErrorCode와 errorMessage를 이용하는 방법 <- 가장 많이 사용하는 방법
GlobalException Handler
@Slf4j
@RestControllerAdvice
public class GlobalExceptionHandler {
@ExceptionHandler(AccountException.class)
public ErrorResponse handleAccountException(AccountException e) {
log.error("{} is occurred, {}", e.getErrorCode(), e.getMessage());
return new ErrorResponse(e.getErrorCode(), e.getMessage());
}
@ExceptionHandler(DataIntegrityViolationException.class)
public ErrorResponse handleDataIntegrityViolationException(DataIntegrityViolationException e) {
log.error("DataIntegrityViolationException is occurred", e);
return new ErrorResponse(INVALID_REQUEST, INVALID_REQUEST.getDescription());
}
@ExceptionHandler(Exception.class)
public ErrorResponse handleAccountException(Exception e) {
log.error("Exception is occurred", e);
return new ErrorResponse(
INTERNAL_SERVER_ERROR,
INTERNAL_SERVER_ERROR.getDescription());
}
}
@RestControllerAdvice 애노테이션을 사용하여 모든 @RestController에서 발생하는 예외를 전역적으로 처리할 수 있도록 설정된 글로벌 예외 처리기이다.
해당 클래에서 정의된 @ExceptionHandler메서드는 특정 예외가 발생했을 때 이를 처리하고, 그에 맞는 응답을 반환한다.
Service계층에서 예외가 발생하면 해당 예외는 Service 메서드를 호출한 Contorller로 전파된다. 그리고 해당 Excpetion이 Controller에서 처리되지 못하면 GlobalExceptionHandler가 해당 에러를 잡아 처리한다.
'프로젝트 이슈 및 몰랐던점 정리 > StockDividendAPI' 카테고리의 다른 글
[설정] Spring Security와 JWT로 로그인 기능 구현 (0) | 2024.10.07 |
---|---|
[설정] Redis Cache 사용하기 및 스프링부트로 Redis 접근하기 (0) | 2024.10.07 |
[설정] 복합 유니크 키 설정 및 DB Index (0) | 2024.10.07 |
[설정] 삽입하려는 데이터의 중복 키 발생 시 레코드 무시하고 삽입하는 방법 (0) | 2024.10.07 |
[설정] 백엔드 API Pageable 사용하기 (0) | 2024.10.07 |