ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • [Spring] HTTP 응답 메시지 만들기 ( Model, @ResponseBody, @ResponseEntity)
    Back-End/Spring Boot 2022. 10. 19. 10:49

     

    지난 포스팅에선 HTTP 요청 파라미터와 메시지에 대해 알아봤다면, 이번 포스팅에선 HTTP 응답 메시지 보내는 방법을 알아볼까 한다. 이전 포스팅은 아래 링크에서 참조! 

     

     

    https://wonisdaily.tistory.com/120

     

    [Spring Boot] HTTP 요청 파라미터, 메시지 ( @RequestParam, @ModelAttribute, @RequestBody, HttpEntity)

    지난 블로그에서 서블릿에서 HTTP 요청, 응답 메시지를 확인하고 전송할 수 있는 법을 알아봤다. 스프링에선 HttpServletRequest, HttpServletResponse 객체 생성 없이 어노테이션을 사용해서 간단하게 클라

    wonisdaily.tistory.com

     

     

     

    HTTP 응답 메시지를 만드는 방법은 크게 3가지가 있다.

    1. 정적 리소스
    ex) 웹 브라우저에 정적인 HTML, css, js 제공

    2. 뷰 템플릿
    ex) 웹 브라우저에 동적인 HTML을 제공

    3. HTTP 메시지 사용
    ex) HTTP API를 제공하는 경우 HTML이 아닌 데이터를 전달해야 하므로, HTTP 메시지 바디에 JSON과 같은 형식으로 데이터를 실어 보낸다.

     

     

     

    📑 1. 정적 리소스

     

    스프링 부트는 클래스패스의 다음 디렉토리에 있는 정적 리소스를 제공한다. 

    /static, /pubic, /resources, /META-INF/resources 

     

    src/main/resources는 리소스를 보관하는 곳이고, 또 클래스 패스의 시작 경로이다. 따라서 다음 디렉토리에 리소스를 넣어두면 스프링 부트가 정적 리소스로 서비스를 제공한다.

     

     

     

     

     

    📑 2. 뷰 템플릿 

     

    뷰 템플릿을 거쳐서 HTML이 생성되고, 뷰가 응답을 만들어 전달한다. 일반적으로 HTML을 동적으로 생성하는 용도로 사용하지만, 다른 것들도 가능하다. 뷰 탬플릿 경로는 src/main/resources/templates와 같다. 

     

    예시로 컨트롤러에서 뷰 이름을 반환해보자.

     

     

    <thymeleaf를 이용한 view>

    <!DOCTYPE html>
    <html xmlns:th="http://www.thymeleaf.org">
    <head>
        <meta charset="UTF-8">
        <title>Title</title>
    </head>
    <body>
    <!--랜더링 될 때 empty의 text가 ${data}의 값으로 들어옴-->
    <p th:text="${data}">empty</p>
    </body>
    </html>

     

     

    <뷰 템플릿 반환 컨트롤러>

    package hello.springmvc.basic.response;
    
    import org.springframework.stereotype.Controller;
    import org.springframework.ui.Model;
    import org.springframework.web.bind.annotation.RequestMapping;
    import org.springframework.web.servlet.ModelAndView;
    
    @Controller
    public class ResponseViewController {
    
        @RequestMapping("/response-view-v1")
        public ModelAndView responseViewV1(){
            ModelAndView mav = new ModelAndView("response/hello")
                    .addObject("data", "hello!");
            return mav;
        }
    
        @RequestMapping("/response-view-v2")
        public String responseViewV2(Model model){
           model.addAttribute("data", "hello!!");
            return "response/hello";
        }
    }

     

     

     

    요즘은 String을 반환하는 방식을 더 많이 사용한다. String을 반환하는 경우 View or HTTP 메시지로 값을 반환할 수 있는다. 만약 @ResponseBody 어노테이션이 메서드 위에 있다면 이는 뷰 리졸버를 실행하지 않고, HTTP 메시지 바디에 직전 reponse/hello라는 문구가 띄워지는 것이고, @ResponseBody 어노테이션이 없다면 response/hello로 뷰 리졸버가 실행되어 뷰를 찾고 렌더링한다.

     

     

     

     

     

     

    📑 3. HTTP 응답 - HTTP API, 메시지 바디에 직접 입력

     

    HTTP API를 제공하는 경우 HTML이 아니라 데이터를 전달해야 하므로, HTTP 메시지 바디에 JSON 같은 형식으로 데이터를 실어 보낸다. 

     

    package hello.springmvc.basic.response;
    
    import hello.springmvc.basic.HelloData;
    import lombok.extern.slf4j.Slf4j;
    import org.springframework.http.HttpStatus;
    import org.springframework.http.ResponseEntity;
    import org.springframework.stereotype.Controller;
    import org.springframework.web.bind.annotation.GetMapping;
    import org.springframework.web.bind.annotation.ResponseBody;
    import org.springframework.web.bind.annotation.ResponseStatus;
    
    import javax.servlet.http.HttpServletRequest;
    import javax.servlet.http.HttpServletResponse;
    import java.io.IOException;
    
    @Slf4j
    @Controller
    public class ResponseBodyController {
    
        @GetMapping("/response-body-string-v1")
        public void responseBodyV1(HttpServletResponse response) throws IOException{
            response.getWriter().write("ok");
        }
    
        @GetMapping("/response-body-string-v2")
        public ResponseEntity<String> responseBodyV2() {
            return new ResponseEntity<>("ok", HttpStatus.OK);
        }
    
        @ResponseBody
        @GetMapping("response-body-string-v3")
        public String responseBodyV3(){
            return "ok";
        }
    
        @GetMapping("response-body-json-v1")
        public ResponseEntity<HelloData> responseBodyJsonV1(){
            HelloData helloData = new HelloData();
            helloData.setUsername("userA");
            helloData.setAge(12);
            return new ResponseEntity<>(helloData, HttpStatus.OK);
        }
    
    
        //★ REST API 만들 때 이방식을 많이 쓴다.
        @ResponseStatus(HttpStatus.OK)
        @ResponseBody
        @GetMapping("response-body-json-v2")
        public HelloData responseBodyJsonV2(){
            HelloData helloData = new HelloData();
            helloData.setUsername("userA");
            helloData.setAge(12);
            return helloData;
        }
    
    
    
    
    }

     

     

    📌 responseBodyV1

    : 이전에서도 다뤘듯이 HttpServletResponse 객체를 통해 HTTP 메시지 바디에 직접 ok 메시지를 전달한다. 

    response.getWriter().write("ok");

     

     

    📌 responseBodyV2

    : ResponseEntity 대신 HttpEntity를 사용해도 된다. why? ReponseEntity는  HttpEntity를 상속 받았는데, HttpEntity는 HTTP 메시지의 헤더, 바디 정보를 갖고있기 때문이다. ResponseEntity는 여기에 더해 HTTP 응답 코드를 설정할 수 있다. 

    return new ResponseEntity<>("ok", HttpStatus.OK);

     

     

    📌 responseBodyV3

    : @ResponseBody를 사용하면 view를 사용하지 않고, HTTP 메시지 컨버터를 통해 HTTP 메시지를 직접 입력할 수 있다. ResponseEntity도 동일한 방식으로 동작한다. 

     

     

     

    📌 responseBodyJsonV1

    : Json 데이터를 보내기 해 ResponseEntity에 HelloData 형태를 반환한다. HTTP 메시지 컨버터를 통해 JSON 형식으로 변환되어 반환된다. 메시지 컨버터는 다음 포스팅에서 다룰 예정

     

     

     

     

    📌 responseBodyJsonV2

    : ResponseEntity를 사용한 responseBodyJsonV1은 응답 코드를 설정할 수 있는데, V2는? 바로 @ResponseStatus() 에너테이션을 사용하면 응답코드 설정이 가능하다. 물론) 에너테이션이기에 응답 코드를 동적으로 변경할 수 없다. 어떤 상황에 맞게 응답 코드를 지정하고 싶다면 V1 방식을 사용하자. 

     

     

     

    반응형

    댓글

Designed by Tistory.