Spring Boot | Spring MVC의 간단한 사용법 | 여러가지 응답의 반환 방법


Spring MVC의 컨트롤러 메소드에서 사용할 수 있는 반환 값에 어떤 것이 있는지, 어떤 방법이 있는지 대해 설명한다.

@Controller와 @RestController의 차이

먼저 @Controller와 @RestController의 차이를 설명한다.

Spring MVC에서 컨트롤러 클래스에 어노테이션으로 @Controller 또는 @RestController을 붙인다.

@Controller는 주로 Web 페이지의 컨트롤러에서 사용한다.
Web 페이지용 컨트롤러는 JSP나 템플릿 엔진 View로 전환 응답의 HTML을 생성하기 때문에 기본적으로 메소드의 반환 값은 View 전환 대상을 지정하는 데 사용한다.

@RestController는 Json이나 XML 등을 반환 WebAPI 용 컨트롤러로 사용한다.
이것은 View로 전환하지 않기 때문에 메소드의 반환 값은 응답(response)의 내용(content)이 된다.

@Controller

반환 값을 String으로 한다.

View 이동 페이지를 지정하는 가장 간단한 방법이다.

@RequestMapping("/method1")
public String method1() {
    return "/index.html";
}

반환 값을 ModelAndView으로 한다.

ModevAndView를 사용하면 View로 전달하려는 정보를 함께 반환할 수 있다.

@RequestMapping("/method2")
public ModelAndView method2() {
    ModelAndView modelAndView = new ModelAndView();
    modelAndView.addObject(new User("kimkc"));
    modelAndView.setViewName("/index.html");
    return modelAndView;
}

포워드

반환 값으로 지정하여 이동처로 “forward:“를 붙이면 다른 컨트롤러 메소드로 이동한다.

@RequestMapping("/forward1")
public String forward1() {
    return "forward:method1";
}

리다이렉트

리다이렉트하려면 “redirect:“를 붙인다.

@RequestMapping("/redirect1")
public String redirect1() {
    return "redirect:method1";
}

외부 URL을 지정하는 경우도 있다.

@RequestMapping("/redirect2")
public String redirect2() {
    return "redirect:https://www.google.co.jp/";
}

컨트롤러에서 직접 텍스트 콘텐츠를 반환한다.

메소드에 @ResponseBody를 붙이면 반환 값으로 직접 응답 내용을 반환할 수있다.

    @RequestMapping("/text1")
    @ResponseBody
    public String text1() {
        return "text content";
    }

HttpServletResponse에서 텍스트 콘텐츠를 반환한다.

반환 값을 void로하고 HttpServletResponse를 인자로 받도록하면 직접 응답을 쓸 수도 있다.

@RequestMapping("/text2")
public void text2(HttpServletResponse res) throws IOException {
    res.getWriter().write("text content");
}

@RestController

반환 값으로 텍스트 콘텐츠를 반환한다.

@RestController을 붙인 컨트롤러 메소드에서는 @ResponseBody를 사용하지 않고도 반환 값이 응답 내용이 된다.

@RequestMapping("/text1")
public String text1() {
        return "text content";
}

HttpServletResponse에서 텍스트 콘텐츠를 반환한다.

@Controller의 경우와 마찬가지로 HttpServletResponse에서 직접 콘텐츠를 쓸 수 있다.

@RequestMapping("/text2")
public void text2(HttpServletResponse res) throws IOException {
    res.getWriter().write("text content");
}

콘텐츠 형식을 지정한다.

콘텐츠 형식을 @RequestMapping의 produces으로 지정한다.

@RequestMapping(value = "/xml1", produces = "application/xml")
public String xml1() {
    return "<a><b>content</b></a>";
}

org.springframework.http.MediaType 클래스에 콘텐츠 형식의 상수가 정의되어 있으므로 이것을 사용하면 좋다.

@RequestMapping(value = "/xml2", produces = MediaType.APPLICATION_XML_VALUE)
public String xml2() {
    return "<a><b>content</b></a>";
}

HTTP 상태 및 응답 헤더를 지정한다.

HTTP 상태 및 콘텐츠 형식 이외의 응답 헤더를 지정하고 싶을 때는 반환 값을 ResponseEntity한다.

@RequestMapping("/responseEntity")
public ResponseEntity<String> responseEntity() {
    HttpHeaders headers = new HttpHeaders();
    headers.add("header1", "heaer1-value");
    HttpStatus status = HttpStatus.NOT_FOUND;
    return new ResponseEntity<String>("text content", headers, status);
}

JSON을 반환한다.

메소드의 반환 값을 임의의 클래스로하면, SpringMVC가 Jackson을 사용하여 json로 변경하여 반환해준다.

@RequestMapping("/json")
public List<User> json() {
    return Arrays.asList(new User("kim", "kc"), new User("kim", "sj"));
}
[
    {
        "lastName": "kim",
        "firstName": "kc"
    },
    {
        "lastName": "kim",
        "firstName": "sj"
    }
]

파일 다운로드

흔히 볼 샘플에서는 HttpServletResponse 직접 쓰는 경우가 많을 거다.

@RequestMapping("/file1")
public void file1(HttpServletResponse res) throws IOException {
    File file = new File("pom.xml");
    res.setContentLength((int) file.length());
    res.setContentType(MediaType.APPLICATION_XML_VALUE);
    FileCopyUtils.copy(new FileInputStream(file), res.getOutputStream());
}

반환 값을 org.springframework.core.io.Resource 인터페이스하면 더 쉽게 구현할 수 있다.

@RequestMapping(value = "/file2", produces = MediaType.APPLICATION_XML_VALUE  public Resource file2() {
    return new FileSystemResource("pom.xml");
}

반환 값이 Resource이면 Content-Length는 자동으로 설정 해준다.

org.springframework.core.io.Resource의 구현 클래스에서 자주 사용할 것 같은 것을 아래와 같다.

  • FileSystemResource
  • ClassPathResource
  • ServletContextResource
  • ByteArrayResource
  • InputStreamResource

그밖에

이외에도 그 밖에도 방법은 여러가지 있을 수 있다. 더 자세하게 알고 싶다면 Spring Framework 문서 등을 참조하기 바란다.