Spring Boot - @Controller의 핸들러 메소드 반환형

h.Im·2024년 9월 9일

Springboot 기초

목록 보기
17/17
post-thumbnail

@Controller의 핸들러 메소드가 주로 반환하는 반환형은 어떤 것들이 있는지 살펴보고, ModelAndView 반환형과 타임리프 템플릿에 대해서 가볍게 알아도보록 하겠습니다.

String

  • 주로 View의 이름을 반환하는 용도로 사용됩니다.
  • 실습해보지는 않았지만, View Resolver에 의해 뷰 템플릿이 반환되게 됩니다.
@Controller
public class MyController {
    @GetMapping("/home")
    public String home() {
        return "home";
    }
}

위와 같이 코드 작성 시, "home.jsp" 또는 "home.html" 같은 템플릿이 렌더링됩니다.


void

  • 반환값이 없을 경우, Spring은 요청 URL에 따라 기본적으로 뷰를 찾습니다.
  • URL이 "/home"이라면 "home.jsp" 또는 "home.html"을 렌더링할 수 있습니다.

String 반환의 경우 뷰 이름을 직접 반환하므로 반환된 이름을 이용해 뷰 리졸버가 뷰 파일을 찾고, void 반환의 경우 요청 URL을 사용해 뷰 이름을 추론하고, 그 이름을 사용해 뷰 리졸버가 해당 뷰 파일을 찾습니다. URL을 기준으로 뷰 이름을 추론하는 것은 Spring MVC의 동작입니다.


ResponseEntity

  • HTTP 응답을 세밀하게 제어할 수 있는 반환형입니다.
  • 상태 코드, 헤더, 바디를 직접 설정할 수 있습니다.
  • 주로 RESTful API를 개발할 때 사용됩니다.
@Controller
public class MyController {
    @GetMapping("/home")
    public ResponseEntity<String> home() {
        return new ResponseEntity<>("Hello, World!", HttpStatus.OK);
    }
}

@ResponseBody 또는 Object

  • 메소드의 반환값을 JSON, XML 등으로 변환하여 HTTP 응답의 바디로 직접 반환할 수 있습니다.
  • 주로 REST API에서 사용되며, @RestController에서는 기본적으로 모든 메소드가 @ResponseBody를 포함합니다.
@Controller
public class MyController {
    @GetMapping("/home")
    @ResponseBody
    public String home() {
        return "Hello, World!";
    }
}

코드상으론 String 반환형과 동일해 보이지만, @ResponseBody 어노테이션이 붙음으로써 Spring MVC가 반환된 값을 처리하는 방식이 달라집니다. @ResponseBody가 붙으면 Spring은 반환된 데이터를 뷰 이름으로 해석하지 않고, 반환된 값을 HTTP 응답의 본문(body)으로 직접 사용합니다.


DeferredResult / CompletableFuture

  • 비동기 처리를 위한 반환형입니다.
  • 비동기 요청을 처리할 때 주로 사용되며, 서버가 요청을 즉시 처리하지 않고 일정 시간 후에 응답해야 할 경우 사용합니다.
@Controller
public class MyController {
    @GetMapping("/async")
    public DeferredResult<String> async() {
        DeferredResult<String> output = new DeferredResult<>();
        // 비동기 작업 완료 후 output.setResult("result") 호출
        return output;
    }
}

ModelAndView

  • 뷰 이름과 함께 모델 데이터를 함께 반환할 수 있습니다.
  • 이 방법을 사용하면 뷰와 데이터를 동시에 설정할 수 있습니다.
@Controller
public class MyController {

    @GetMapping("/greeting")
    public ModelAndView greeting() {
        // ModelAndView 객체 생성, 뷰 이름을 "greeting"으로 설정
        ModelAndView mav = new ModelAndView("greeting");
        
        // 모델에 데이터 추가
        mav.addObject("name", "John");
        
        // ModelAndView 반환
        return mav;
    }
}

위 예시에서 greeting은 템플릿 명, addObject는 템플릿에 전달한 데이터입니다. 타임리프 템플릿 예시는 아래와 같습니다.

<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<head>
    <title>Greeting</title>
</head>
<body>
    <h1 th:text="'Hello, ' + ${name} + '!'">Hello, Guest!</h1>
</body>
</html>

${name} 부분에 John이 노출되는 방식으로 동작합니다.

0개의 댓글