https://lucete-stellae.tistory.com/96
[SpringBoot] Rest Api Sample ๋ง๋ค๊ธฐ #1
๊ธฐ์กด์ ๊ธํ๊ฒ ์งํํ ์ฌ๋ด SMS API ์๋น์ค๋ฅผ ๋ง๋ค๊ณ ๋์, ์ ๋ฆฌ๋ ํ ๊ฒธ ์ํ๋ก REST API ์ํ ํ๋ก์ ํธ๋ฅผ ๋ง๋ค์ด๋ณด๊ธฐ๋ก ํ๋ค. ๊ธฐ๋ณธ์ ์ธ ๋ฒ์ ์ ๋ณด๋ ๋ค์๊ณผ ๊ฐ๋ค. 1. ๊ธฐ๋ณธ ํ๋ก์ ํธ ์ธํ JDK11 Spring Bo
lucete-stellae.tistory.com
#1์ ์ด์ด์ ์์ ํ ๋ด์ฉ์ ๊ธฐ์ ํฉ๋๋ค.
API ์๋ฌ ์ฒ๋ฆฌ
์๋ฌ๊ฐ ๋ฐ์ํ ์ ์๋ ์ํฉ๋ถํฐ ์ ์ํด๋ณด์
- ์๋น์ค ๋ก์ง ๋ด์์ Exception ์ด ๋ฐ์ํ๋ ๊ฒฝ์ฐ.
- ๋ก์ง ์ธ ์ ์ธ ๋ถ๋ถ ( ์๋ชป๋ URL ํธ์ถ, ๋ฑ ) ์์ ์๋ฌ๊ฐ ๋ฐ์ํ๋ ๊ฒฝ์ฐ.
์ ๋๊ฐ์ง ์ผ์ด์ค์์ ์๋ฌ๊ฐ ๋ฐ์ํ๋๋ผ๋, ๋์ผํ ํฌ๋งท์ผ๋ก ๋๊ฐ๊ฒ๋ ์ ๋ํ๋ ค๊ณ ํ๋ค.
์ฐ์ , ๊ธฐ๋ณธ์ ์ผ๋ก ์ ์ํ ํผ์ ๋ค์๊ณผ ๊ฐ์ต๋๋ค.
{
"result_status": "success",
"result_code": 200,
"result_message": "์์ฒญ์ ์ฑ๊ณตํ์์ต๋๋ค.",
"result": { ... }
}
๊ทธ๋ฆฌ๊ณ ํด๋น ํฌ๋งท์ ์ํ ์๋ต ๊ฐ์ฒด๋ฅผ ์์ฑํฉ๋๋ค. ํด๋น ๊ฐ์ฒด๋ฅผ ํตํด ์ปจํธ๋กค๋ฌ์์ ์๋ต์ ๋ฆฌํดํ ๋๋ return new ResponseEntity<ApiResFormat>(new ApiResFormat(),HttpStatus.OK); ๊ณผ ๊ฐ์ด ๋ฆฌํดํ ์์ ์ ๋๋ค.
package rest.api.sample.response;
import java.util.HashMap;
import lombok.Getter;
import lombok.Setter;
@Getter
@Setter
public class ApiResFormat {
// result_status -> fail / success
private String result_status;
// result_code -> 200 / 4XX / 5XX
private int result_code;
// result_message -> NOT ACCEPTED , EXCEPTION ...
private String result_message;
// result -> result obj
private HashMap<String, Object> result = new HashMap<String, Object>();
/* ๊ฒฐ๊ณผ ์์ */
/*
{
"result_status": "success",
"result_code": 200,
"result_message": "์์ฒญ์ ์ฑ๊ณตํ์์ต๋๋ค.",
"result": {
...
}
}
*/
public ApiResFormat() {
}
public ApiResFormat(String status, int resultCode, String resultMessage, Object resultObj) {
this.result_status = status;
this.result_code = resultCode;
this.result_message = resultMessage;
result.put("data", resultObj);
}
public ApiResFormat(int resultCode, Object resultObj) {
this.result_status = "success";
this.result_code = resultCode;
this.result_message = "์์ฒญ์ ์ฑ๊ณตํ์์ต๋๋ค.";
result.put("data", resultObj);
}
public ApiResFormat(int resultCode, String resultMessage, Object resultObj) {
this.result_status = "success";
this.result_code = resultCode;
this.result_message = resultMessage;
result.put("data", resultObj);
}
public ApiResFormat(String resultMessage, Object resultObj) {
this.result_status = "success";
this.result_code = 200;
this.result_message = resultMessage;
result.put("data", resultObj);
}
public ApiResFormat(Object resultObj) {
this.result_status = "success";
this.result_code = 200;
this.result_message = "์์ฒญ์ ์ฑ๊ณตํ์์ต๋๋ค.";
result.put("data", resultObj);
}
}
์คํจ์ ๊ฒฝ์ฐ์๋ ์คํจ์ ๋ง๊ฒ ๋ฐ๊ฟ ์ค ์๊ฐ์ด๋ค. ์ด์ 1๋ฒ ์ผ์ด์ค์ ๊ฒฝ์ฐ์๋ ์ด๋ป๊ฒ ์ฒ๋ฆฌํ ๊ฒ์ธ๊ฐ์ ๋ํ ๋ด์ฉ์ ๋๋ค.
@RestControllerAdvice, @ExceptionHandler
RestControllerAdvice ๋ ์ปจํธ๋กค๋ฌ ๋จ์ ์ค์ ๋ค์ ํ ์ ์๊ฒ ํด์ฃผ๋ ControllerAdvice ์ ํ์ฅ ๋ฒ์ ์ผ๋ก ์๋ต ๊ฐ์ฒด๋ฅผ ๋ฆฌํดํ ์ ์๋ ๊ฒ์ด ํน์ง์ด๊ณ , ExceptionHandler ๋ Controller ๋จ์์ ๋ฐ์ํ๋ Exception์ ํธ๋ค๋ง ํ ์ ์๋๋ก ํฉ๋๋ค.
๋ฐ๋ผ์, ์๋ํฌ์ธํธ ์ปจํธ๋กค๋ฌ ๋จ์์ ๋ฐ์ํ๋ Exception์ ์บ์นํ์ฌ ์ํ๋ ํฌ๋งท์ผ๋ก ๋ฆฌํดํ๊ธฐ ์ํด ์๋์ ๊ฐ์ด ์ค์ ํ์ต๋๋ค.
package rest.api.sample.error;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.RestControllerAdvice;
import rest.api.sample.response.ApiResFormat;
@RestControllerAdvice
public class GlobalExceptionHandler extends RuntimeException {
@ExceptionHandler(Exception.class)
public ResponseEntity<ApiResFormat> globalException(Exception ex) {
return new ResponseEntity<ApiResFormat>(new ApiResFormat("fail", 500, "์์ฒญ์ ์คํจํ์์ต๋๋ค.", null),
HttpStatus.INTERNAL_SERVER_ERROR);
}
}
์ด๋ ๊ฒ ํ๋ฉด ์ปจํธ๋กค๋ฌ๋ฅผ ํตํด ๋ก์ง ์ํ ์ค ๋ฐ์ํ๋ Exception ์ ์บ์นํ์ฌ ๋ฆฌํดํด์ค ์ ์๊ฒ ๋ฉ๋๋ค.
๋ค์์, ๋ก์ง ์ธ ์๋ฌ ์ํฉ์ ๋ํ ์ฒ๋ฆฌ์ ๋๋ค.
DefaultErrorAttributes.class
DefaultErrorAttributes ๋ ๊ธฐ๋ณธ์ ์ผ๋ก ์คํ๋ง ๋ถํธ์์ ์๋ฌ ๋ฐ์ ์ ๋ฆฌํดํ๋ ๊ฐ์ฒด๋ฅผ ์ปจํธ๋กค ํ ์ ์๊ฒ ํด์ฃผ๋ ํด๋์ค์ ๋๋ค. ๊ธฐ๋ณธ์ ์ผ๋ก ์คํ๋ง ๋ถํธ๋ ์๋ฌ ๋ฐ์ ์, JSON ํํ๋ก ์๋ฌ๋ฅผ ๋ฆฌํดํ๊ฒ ๋๋๋ฐ ๊ทธ ๋ด๋ถ์ ํญ๋ชฉ๋ค์ ํด๋น ํด๋์ค๋ฅผ ํตํด ์ ์ดํ ์ ์์ต๋๋ค.
package rest.api.sample.error;
import java.util.HashMap;
import java.util.Map;
import org.springframework.boot.web.error.ErrorAttributeOptions;
import org.springframework.boot.web.servlet.error.DefaultErrorAttributes;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.WebRequest;
@Component
public class RestResponseEntityExceptionHandler extends DefaultErrorAttributes {
/**
* @apiNote ์๋ฌ ๋ฐ์ ์, repsonse ํต์ผ์ ์ํ ๋ฉ์๋
* @param webRequest
* @param options
* @return
* result_status = FAIL
* result_message = ์๋ชป๋ ์์ฒญ URL ์
๋๋ค.
*/
@Override
public Map<String, Object> getErrorAttributes(
WebRequest webRequest, ErrorAttributeOptions options) {
HashMap<String, Object> result = new HashMap<String, Object>();
result.put("data", null);
Map<String, Object> errorAttributes = super.getErrorAttributes(webRequest, options);
errorAttributes.put("result_status", "fail");
errorAttributes.put("result_code", Integer.parseInt(errorAttributes.get("status").toString()));
errorAttributes.put("result_message", "ํ์ฉ๋์ง ์์ ์ ๊ทผ ์
๋๋ค.");
errorAttributes.put("result", result);
errorAttributes.remove("timestamp");
errorAttributes.remove("status");
errorAttributes.remove("message");
errorAttributes.remove("error");
errorAttributes.remove("path");
if (errorAttributes.containsKey("trace"))
errorAttributes.remove("trace");
return errorAttributes;
}
}
๋ฐ๋ผ์, ์ ํด๋์ค๋ฅผ ํตํด ํ์ํ ํญ๋ชฉ์ ์ถ๊ฐํ๊ณ ๋ณด์ฌ์ค ํ์๊ฐ ์๋ trace ํญ๋ชฉ์ด๋ ๋ค๋ฅธ ํญ๋ชฉ๋ค์ ์ ์ธ๋ฅผ ์์ผ ์๋ฌ ๋ฐ์์ response ํํ๋ฅผ ์ต๋ํ ํต์ผ ์ํค๋๋ก ์์ฑํ์์ต๋๋ค.

'๐ฎSpring' ์นดํ ๊ณ ๋ฆฌ์ ๋ค๋ฅธ ๊ธ
[SpringBoot] H2 Database CSV ๋ฐ์ดํฐ Import ํ๊ธฐ (0) | 2022.07.29 |
---|---|
[SpringBoot] Swagger ui 3.0 ์ฐ๋ํ๊ธฐ (0) | 2022.07.18 |
[SpringBoot] Rest Api Sample ๋ง๋ค๊ธฐ #1 (0) | 2022.07.05 |
[SpringBoot] CORS ์ฒ๋ฆฌํ๊ธฐ (0) | 2022.06.28 |
[AOP] AOP Aspect ๋ฅผ ์ด์ฉํ ๋ก๊ทธ ์ฒ๋ฆฌ ํ๊ธฐ (0) | 2022.04.18 |
๋๊ธ