-
[๊ตฌํ] Spring์์ ์๋ฌ๋ฅผ ๋ด๋ 3๊ฐ์ง ๋ฐฉ๋ฒSPRING/PROJECT 2023. 4. 2. 21:48
์๋ฌ๋ฅผ.. ๋ด๋ด ์๋ค ํ๋ก์ ํธ์์ ์๋ฌ๋ฅผ ๋ผ ๋ ๋ด๊ฐ ์ฌ์ฉํ๋ ๋ฐฉ๋ฒ์ ์ด ์ธ ๊ฐ์ง์ด๋ค.
- ResponseEntity ์ฌ์ฉ
- Custom ์์ธ ํด๋์ค ๋ง๋ค๊ธฐ
- ControllerAdvice ์ฌ์ฉํ๊ธฐ
๊ฐ์ธ์ ์ผ๋ก ์์ฃผ ๊ฐ๋จํ ํ๋ก์ ํธ๊ฐ ์๋๋ผ๋ฉด 3๋ฒ์ ์ถ์ฒํ๋ค.
ํ๋์ฉ ๋ด๋ณด์๋ฉด,
1. ResponseEntity ์ฌ์ฉ
์ค๋ช ํ ๊ฒ ์์ ์ ๋๋ก ๋งค์ฐ ๊ฐ๋จํ ๊ฒ์ด ์ฅ์ ์ด๋ค.
๋จ์ ์ ์ฝ๋๊ฐ ์ง์ ๋ถํด์ง๋ค๋ ์ ์ด๋ค.
new ResponseEntity<>({๋ณด๋ผ ๋ฐ์ดํฐ}, HttpStatus.{status});
์ด ํ ์ค๋ง ๋ฆฌํดํ๋ฉด ๋๋ค.
ํ์ง๋ง ์์ธ์ฒ๋ฆฌํ ๊ฒ ์ฌ๋ฌ๊ฐ๊ฐ ๋๋ฉด ๋๋ฌด ๋ณต์กํด์ง๋ค.
@PostMapping("/users/login") public ResponseEntity<HashMap> socialLogin(@RequestBody UserDto.LoginDto loginDto) { HashMap<String, Object> responseMap = new HashMap<>(); User user = userService.signIn(loginDto.getSocialType(), loginDto.getSocialToken()); if (loginDto.getSocialType().equals("kakao")) { if (user == null) { responseMap.put("status", 404); responseMap.put("message", "ํ์ ์ ๋ณด ์์"); return new ResponseEntity<>(responseMap, HttpStatus.NOT_FOUND); } responseMap.put("status", 200); responseMap.put("message", "๋ก๊ทธ์ธ ์ฑ๊ณต"); responseMap.put("data", new HashMap<String, String>() {{ put("token", jwtTokenProvider.createToken(user.getSocialId(), user.getRoles())); }}); return new ResponseEntity<>(responseMap, HttpStatus.OK); } else { responseMap.put("status", 401); responseMap.put("message", "์์ ํ์ ์ค๋ฅ"); return new ResponseEntity<>(responseMap, HttpStatus.NOT_FOUND); } responseMap.put("status", 404); responseMap.put("message", "ํ์ ์ ๋ณด ์์"); return new ResponseEntity<>(responseMap, HttpStatus.NOT_FOUND); }
์ ๊ฒฝ์ฐ ์๋ต์ ์๋ ๋ชจ์์ผ๋ก ๋๊ฐ๋ค.
{ "message": "ํ์ ์ ๋ณด ์์", "status": 404 }
ResponseEntity๋ฅผ ์ ๋ถ Service ๋จ๊ณ์์ return ํ๊ณ , ๊ทธ๋ฅผ ๊ทธ๋๋ก Controller์์ ๋ฐํํ๋ ๋ฐฉ๋ฒ๋ ์๊ธด ํ์ง๋ง,
์ฝ๋ ๊ฐ๋ ์ฑ์ด ๋ณ๋ก์ผ ๊ฒ ๊ฐ๋ค.
๊ฐ๋จํ๊ฒ ์๋ฌ๋ฅผ ๋ด์ผํ ๋ ์ข์ ๋ฐฉ๋ฒ์ด๋ค.
2. Custom ์์ธ ํด๋์ค ๋ง๋ค๊ธฐ
์ญ์ ๋งค์ฐ ๊ฐ๋จํ๋ค.
ํ์ง๋ง ๋ชจ๋ ์๋ฌ์ ๋ํด ์ ๋ถ ํด๋์ค๋ฅผ ๋ง๋ค์ด์ผ ํ๋ค๋ ๋จ์ ์ด ์๋ค.
@ResponseStatus(code = HttpStatus.NOT_FOUND, reason = "ํด๋น id์ ํด๋นํ๋ ๋ฐ์ดํฐ๊ฐ ์์ต๋๋ค.") public class NotFoundIdException extends RuntimeException{ }
์ด๋ฐ ํด๋์ค๋ฅผ ํ๋ ๋ง๋ค์ด์ ํ์ํ ๋ Throw ํด์ฃผ๋ฉด ๋๋ค.
{ "timestamp": "2023-04-02T13:13:11.287+00:00", "status": 400, "error": "Bad Request", "trace": "{trace}", "message": "์๋ชป๋ ์ฟผ๋ฆฌ ํ๋ผ๋ฏธํฐ ๊ฐ ์ ๋๋ค.", "path": "/api/dresses/search" }
์ด๋ฐ ํ์์ ๋ฐ์ดํฐ๊ฐ ์ ์ก๋๋ค.
3. ControllerAdvice ์ฌ์ฉํ๊ธฐ
๊ฐ์ฅ ์ถ์ฒํ๋ ๋ฐฉ๋ฒ์ด๋ค.
๊น๋ํ๊ณ , ๋ง์ ์๋ฌ๋ฅผ ๋ง์ ํด๋์ค๋ฅผ ๋ง๋ค์ง ์๊ณ ๋ ํด๊ฒฐํ ์ ์๋ค.
@RequiredArgsConstructor @Getter public enum ErrorResponseStatus { BAD_REQUEST_WRONG_TAG_EXCEPTION(HttpStatus.BAD_REQUEST, "์๋ชป๋ ํ๊ทธ"), UNAUTHORIZED_WRONG_SOCIAL_TYPE(HttpStatus.UNAUTHORIZED, "์๋ชป๋ ์์ ํ์ "), UNAUTHORIZED_INVALID_SOCIAL_TOKEN(HttpStatus.UNAUTHORIZED, "์๋ชป๋ ์์ ํ ํฐ"), NOT_FOUND_USER_EXCEPTION(HttpStatus.NOT_FOUND, "ํ์ ์ ๋ณด ์์"), NOT_FOUND_PASSWORD_EXCEPTION(HttpStatus.NOT_FOUND, "๋น๋ฐ๋ฒํธ ๋ถ์ผ์น"), CONFLICT_DUPLICATED_NICKNAME(HttpStatus.CONFLICT, "์ค๋ณต๋ ๋๋ค์"); private final HttpStatus code; private final String message; }
์ด๋ฐ enum ํ์ผ์ ํ๋ ์์ฑํ๊ณ ,
์ด enum ํ์ผ๋ก ์์ฑ๋ ์ ์๋ Exception ํ์ผ์ ์์ฑํ๋ค.
@Getter @AllArgsConstructor public class CustomException extends RuntimeException { private final ErrorResponseStatus errorResponseStatus; }
๋ค์ ์ Exception ํ์ผ์ handleํ๋ ExceptionHandler๋ฅผ ๋ง๋ค์ด์ค๋ค.
@RestControllerAdvice ๋๋ @ControllerAdvice๋ฅผ ๋ถ์ฌ์ผ Spring์ด ์ธ์ํด์ ์๋ฌ๋ฅผ ๋ฐ์์์ผ์ค๋ค.
@RestControllerAdvice public class ExceptionHandler extends ResponseEntityExceptionHandler{ @org.springframework.web.bind.annotation.ExceptionHandler(value = CustomException.class) protected ResponseEntity<ResponseTemplate> handleCustomException(CustomException e) { return ResponseTemplate.toResponseEntity(e.getResponseCode()); } }
ResponseTemplete์ toResponseEntity ๋ฉ์๋๋ฅผ ๋ฆฌํดํ๋ฉด์ ์๋ฌ๊ฐ ๋ฐ์ํ๋๋ฐ,
toResponseEntity์์๋ ErrorResponseStatus์ status์ ๋ด์ฉ์ ๋ฐ์์ ResponseEntity์ ์ง์ด ๋ฃ์ด์ ์ 1๋ฒ๊ณผ ๊ฐ์ ๋ฐฉ๋ฒ์ผ๋ก ์๋ฌ๋ฅผ ๋ฐ์์ํค๊ณ ์๋ค.
@Builder @AllArgsConstructor public class ResponseTemplate { public int status; public String message; private final LocalDateTime timestamp = LocalDateTime.now(); public static ResponseEntity<ResponseTemplate> toResponseEntity(ErrorResponseStatus errorResponseStatus) { return ResponseEntity .status(errorResponseStatus.getHttpStatus()) .body(ResponseTemplate.builder() .status(errorResponseStatus.getHttpStatus().value()) .message(errorResponseStatus.getMessage()) .build() ); } }
์ 4๊ฐ์ ํด๋์ค๋ง ๋ง๋ค์ด์ฃผ๋ฉด ์ ๋ง์ ์๋ฌ๋ฅผ ์ฝ๋๋ฅผ ์ฌํ์ฉํ์ฌ ๋ฐ์์ํฌ ์ ์์ด ๊ฐ์ฅ ์ ์ฉํ๋ ๋ฐฉ๋ฒ์ด๋ค.
1, 2๋ฒ๋ณด๋ค๋ ์กฐ๊ธ ๋ณต์กํ๊ฒ ๋๊ปด์ง ์ ์๋ค๋ ๋จ์ ์ ์์ผ๋ ์ํฉ์ ๋ฐ๋ผ ํ์ํ ๋ฐฉ๋ฒ์ ์ฌ์ฉํ๋ฉด ์ข์ ๊ฒ ๊ฐ๋ค.
'SPRING > PROJECT' ์นดํ ๊ณ ๋ฆฌ์ ๋ค๋ฅธ ๊ธ
[๊ตฌํ] Spring์์ Firebase ํธ์์๋ฆผ ๊ตฌํํ๊ธฐ (0) 2023.09.26 [๊ตฌํ] Spring์์ ์นด์นด์คํก ๋ก๊ทธ์ธ (0) 2023.09.25 [๊ตฌํ] ์คํ๋ง์ผ๋ก ๋น๋ฐ๋ฒํธ ์ฌ์ค์ ๋งํฌ ๋ง๋ค๊ธฐ (0) 2021.12.12 [๊ตฌํ] ์คํ๋ง์ผ๋ก ์ด๋ฉ์ผ ์ธ์ฆ ์ฝ๋ ๋ฐ๊ธ, ์ธ์ฆํ๊ธฐ (0) 2021.12.12 [๋ฐฐํฌ] ์คํ๋ง ํ๋ก์ ํธ EC2๋ก AWS์ ๋ฐฐํฌํ๊ธฐ + RDS ๋ง๋ค๊ธฐ (0) 2021.12.09