이번 강의(12강)를 보면서 가장 헷갈렸던 건 이거였다.
이 글은 강의에서 나온 말 + 내가 직접 헷갈렸던 질문을 전부 정리한 기록이다.
@Controller
public class TestController {
@GetMapping("/test")
public String test() {
return "test"; // test.html 찾으러 감
}
}
@RestController
= @Controller + @ResponseBody
@RestController
public class ApiController {
@GetMapping("/api/test")
public String test() {
return "hello"; // JSON "hello"
}
}
👉 핵심 차이
| 구분 | 반환 해석 |
|----|----|
@Controller | 뷰 이름 |
@RestController | HTTP Body(JSON) |
전역 컨트롤러 보조 장치 (특히 예외 처리)
@ControllerAdvice
public class GlobalExceptionHandler {
@ExceptionHandler(Exception.class)
public String handle(Exception e) {
return "error"; // ❗ 뷰 이름으로 해석
}
}
⚠️ 여기서 중요한 점
➡️ @ControllerAdvice는 기본적으로 뷰를 반환하려고 한다
@RestControllerAdvice
= @ControllerAdvice + @ResponseBody
@RestControllerAdvice
public class GlobalExceptionHandler {
@ExceptionHandler(Exception.class)
public RsData<Void> handle(Exception e) {
return new RsData<>("500-1", "에러 발생", null);
}
}
👉 이걸 안 쓰면?
📌 강의에서 404 떴던 이유 = ResponseBody가 없었기 때문
강의에서 이런 말이 나왔다.
“ResponseEntity를 리턴하는 건 상관없다”
ResponseEntity는 이미 HTTP 응답 객체다.
return ResponseEntity
.badRequest()
.body(new RsData<>("400-1", "에러", null));
여기서 제일 큰 의문이 생겼다.
IllegalArgumentException 쓰면 안 되나?
IllegalStateException도 400 아닌가?
throw new IllegalArgumentException("메시지");
문제:
throw new ServiceException("415-1", "메시지");
ServiceException은 의도적으로 만든 서비스 전용 예외다.
resultCode
msg
data = null
👉 즉,
“이 에러는 어떤 종류고, 클라이언트에 뭘 보여줄지”
를 예외 자체가 알고 있음
강의 핵심 포인트 👇
상황에 따라 HTTP 응답 코드를 바꾸고 싶기 때문
예:
ServiceException → GlobalExceptionHandler →
resultCode 기반으로 statusCode 결정 가능
@ExceptionHandler(ServiceException.class)
public RsData<Void> handle(ServiceException ex, HttpServletResponse response) {
RsData<Void> rsData = ex.getRsData();
response.setStatus(rsData.statusCode());
return rsData;
}
역할 분리:
@RestController = @Controller + @ResponseBody
@RestControllerAdvice = @ControllerAdvice + @ResponseBody
이번 강의는
헷갈렸던 게 정상이고,
이걸 질문으로 정리한 지금이 진짜 실력이 쌓이는 구간이라고 느꼈다.