[개발일지11] @Controller, @RestController, @ControllerAdvice, @RestControllerAdvice

김희주·2023년 3월 15일
0

개발일지

목록 보기
10/10
post-thumbnail

1. @Controller vs @RestController

  • Spring에서 컨트롤러를 지정해주기 위해서는 @Controller@RestController를 사용한다.
    1-1. @Controller
  • 전통적인 SPring MVC 방식
  • view 또는 Data(ex.Json) 반환
  • Controller로 객체를 반환할 때는 일반으로 ResponseEntity로 감싸서 반환
  • 아래 예시는 객체 반환 / 반환
@Controller
@RequiredArgsConstructor
public class TestController {

    private final TestService testService;

    @GetMapping(value = "/test")
    public @ResponseBody ResponseEntity<Test> findUser(@RequestParam("testName") String testName){
        return ResponseEntity.ok(testService.findUser(test));
        또는 
        return ResponseEntity<>(dto, header, HttpStatus.OK);
    }
    
    @GetMapping(value = "/test/detailView")
    public String detailView(Model model, @RequestParam("testName") String testName){
        Test test = testService.findTest(testName);
        model.addAttribute("test", test);
        return "/test/detailView";
    }
}

1-2. @RestController

  • Restful 웹서비스의 컨트롤러
  • @Controller + @ResponseBody 합쳐진 것.
  • 주 용도 : Json 형태로 객체 데이터를 반환
  • 단점 ==> httpStatus를 설정할 수 없음.
    예를 들어 어떤 객체의 생성 요청이라면 201 CREATED를 기대할 것이지만 객체를 그대로 반환하면 HttpStatus를 설정해줄 수 없습니다. 그래서 객체를 상황에 맞는 ResponseEntity로 감싸서 반환해주어야 합니다.(출처)
@RestController
@RequestMapping("/user")
@RequiredArgsConstructor
public class TestController {

    private final TestService testService;

    @GetMapping(value = "/test")
    public User findTest(@RequestParam("testName") String testName){
        return testService.findTest(test);
    }

    @GetMapping(value = "/test")
    public ResponseEntity<Test> findUserWithResponseEntity(@RequestParam("testName") String testName){
        return ResponseEntity.ok(testService.findTest(test));
    }
}

2. @ControllerAdvice vs @RestCOntrollerAdvice

  • 두 개의 차이는 @Controller와 RestController와 같은데, @RestControllerAdvice는 @ControllerAdvice와 달리 @ResponseBody가 붙어 있어 응답을 Json으로 내려준다는 점에서 다르다.(출처)

2-1. @ControllerAdvice

  • ControllerAdvice 어노테이션에는 @Component 어노테이션이 있어서 ControllerAdvice가 선언된 클래스는 스프링 빈으로 등록된다.
  • @Controller나 @RestController에서 발생한 예외를 한 곳에서 관리하고 처리할 수 있게 도와주는 애너테이션
  • 단순히 예외만 처리하고 싶다면 @ControlllerAdvice를 적용하면 되고
  • 응답으로 객체를 리턴해야한다면 @RestControllerAdvice를 적용하면 된다.

2-2. @RestControllerAdvice

  • @RestController + Advice기능(객체 반환 기능)

3. 사용자 지정 상태 코드 반환 (출처)
3-1. ResponseEntity 사용

@RequestMapping(value = "/controller", method = RequestMethod.GET)
@ResponseBody
public ResponseEntity sendViaResponseEntity() {
    return new ResponseEntity(HttpStatus.NOT_ACCEPTABLE);
}

3-2. 예외클래스에 @ResponseStatus 사용

@RequestMapping(value = "/exception", method = RequestMethod.GET)
@ResponseBody
public ResponseEntity sendViaException() {
    throw new ForbiddenException();
}

" / exception "에 대한 GET 요청을 받으면 Spring은 ForbiddenException 을 던질 것 입니다. 이것은 별도의 클래스에서 정의 할 사용자 지정 예외입니다.

@ResponseStatus(HttpStatus.FORBIDDEN)
public class ForbiddenException extends RuntimeException {}

이 예외에는 코드가 필요하지 않습니다. 모든 작업은 @ResponseStatus 어노테이션에 의해 수행됩니다 .
3-3. @ContollerAdvice 및 @ExceptionHandler 사용


※ 주의할 점은, 프로젝트에 하나의 @ControllerAdvice만 관리하는 것을 권장합니다.


요약: @Controller도 객체 반환은 되나 그러려면 @ResponseBody를 붙여야하므로 @RestController를 사용하는게 나음. 하지만 @RestController는 상태값반환이 안 되므로 (Http status 어쩌구)를 사용할 수 없으므로 적절한 ResponseEntity를 이용해야함(ex. ResponseEntity.ok)

profile
백엔드 개발자입니다 ☘

0개의 댓글