본문 바로가기
BE/🍃 Spring

[Spring Boot] Controller와 RestController 차이와 ResponseBody

by 틴디 2024. 9. 22.
반응형

@Controller Vs. @RestController

  • RestController는 Spring Boot 4.0 부터 Restful 서비스 개발을 위해 추가됨
  • RestController는 Controller + ResponseBody 즉, Controller임을 의미하면서 ResponseBody인 RestApi임을 의미한다
  @Controller @RestController
사용하는 곳 Web Application 개발에 사용됨 Restful Web Service 개발에 사용됨
반환 타입 html과 같은 View를 반환 json, XML과 같은 Response 반환

 

@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Controller
@ResponseBody
public @interface RestController {
    @AliasFor(
        annotation = Controller.class
    )
    String value() default "";
}
  • RestController를 확인해 보면 @Controller와 @ResponseBody 어노테이션을 확인할 수 있다. 

@Controller

implementation 'org.springframework.boot:spring-boot-starter-thymeleaf'
  • jsp가 아닌 templates 파일의 View를 렌더링 하기 위해 build.gradlew에 타임리프 추가 필요
  • View 파일은 resources > templates 에 위치
@Controller
@RequestMapping("/welcome")
public class WelcomeViewController {

    @GetMapping("/hello")
    private String hello(Model model) {
        return "hello";
    }
}
  • @Controller 어노테이션을 사용한 클래스는 View를 반환하는 컨트롤러가 된다 (해당 클래스에서 RestApi를 반환하는 메소드 추가 가능)
  • 뷰 리졸버는 return 되는 문자열인 "hello"와 같은 뷰 파일 (hello.html, hello.jsp)을 찾아 렌더링한다

 

@RestController

@RestController
@RequestMapping("/api")
public class UserApiController {

    @PostMapping("/user")
    public ResponseEntity<UserRequest> user(
        @RequestBody UserRequest userRequest
    ) {
        return ResponseEntity.ok().body(userRequest);
    }
}

 

  • 클라이언트에게 JSON과 같은 데이터를 반환하며 Rest API 개발에서 주로 사용된다

 

@ResponseBody

  • ResponseBody 애노테이션은 반환하는 값을 View Resolver로 처리하지 않고 HTTP Response Body에 결과를 반영한다.
  • Rest API 개발을 위해 사용된다
  • ResponseBody 애노테이션이 없는 경우 기본적으로 View Resolver에 의해 View로 렌더링을 시도한다
  • RestController는 Contrller + ResponseBody 애노테이션을 가지고 있으므로 ResponseBody 애노테이션을 추가하지 않아도 된다
  • Controller에서 View가 아닌 RestAPI로 동작하고 싶은 경우 ResponseBody 애노테이션을 붙여 사용할 수 있다

잘 못된 사용

@Controller
@RequestMapping("/welcome")
public class WelcomeViewController {
    @PostMapping("/user")
    public UserRequest user(
            @RequestBody UserRequest userRequest
    ) {
        return userRequest;
    }
}
  • org.thymeleaf.exceptions.TemplateInputException: Error resolving template [welcome/user], template might not exist or might not be accessible by any of the configured Template Resolvers에러가 발생
  • 템플릿 파일인 welcom/user를 찾으려 했으나 해당 경로에 파일을 찾지 못해서 발생한 에러
  • View가 아닌 Json 형태의 데이터를 리턴하기 원하므로 @Controller가 아닌 @RestController 사용 혹은 해당 메소드에 @ResponseBody 애노테이션을 추가해야 한다

수정된 예시

@Controller
@RequestMapping("/welcome")
public class WelcomeViewController {
	@PostMapping("/user")
    @ResponseBody
    public UserRequest user(
            @RequestBody UserRequest userRequest
    ) {
        return userRequest;
    }
}

 

혹은 

@RestController
@RequestMapping("/welcome")
public class WelcomeRestController {
	@PostMapping("/user")
    public UserRequest user(
            @RequestBody UserRequest userRequest
    ) {
        return userRequest;
    }
}

 

혹은 아래처럼도 사용 가능하다.

 

@Controller
@RequestMapping("/welcome")
public class WelcomeViewController {
    @PostMapping("/user")
    public ResponseEntity<UserRequest> user(
            @RequestBody UserRequest userRequest
    ) {
        return ResponseEntity.ok().body(userRequest);
    }
}
  • ResponseEntity의 경우 HTTP 응답 객체이며, 데이터를 JSON이나 XML로 변환후 HTTP Response Body를 통해 클라이언트에게 전달한다
  • Spring은 ResponseEntity가 return 되는 경우 자동으로 JSON 직렬화를 통해 Response Body로 반환

 

728x90
반응형

댓글