Spring MVC 기본기능-값 응답

강정우·2023년 12월 5일
0

Spring-boot

목록 보기
33/73

정적 리소스

  • 응답에는 3가지 종류가 있다. 정적리소스, view template, HTTP message
    이중 정적리소스는 /static , /public , /resources , /META-INF/resources 에 위치하며 여기에 있는 파일은 스프링 부트가 뜨면서 정적리소스로 톰캣을 통해 서빙한다.

동적 리소스

ModelAndView

@RequestMapping("/response-view-v1")
public ModelAndView responseViewV1() {
    ModelAndView mav = new ModelAndView("response/hello")
            .addObject("data", "hello!");
    return mav;
}
  • 가장 기본인 ModelAndView를 만들어서 반환하는 법

Model

@RequestMapping("/response-view-v2")
public String responseViewV2(Model model) {
    model.addAttribute("data", "hello!!");
    return "response/hello";
}
  • String으로 반환하면 뭐다? View를 찾는다~
    참고로 여기는 따로 prefix suffix를 설정하지 않아도 spring 차원에서
    prefix는 classpath:/templates/ 을 suffix는 .html을 제공한다.

경로 생략가능

@RequestMapping("/response/hello")
public void responseViewV3(Model model) {
    model.addAttribute("data", "hello!!");
}
  • 얘는 별로 권장하진 않음 컨트롤로 이름이 path로 되어있을 경우 spring이 컨벤션하게 그냥 찾아서 보내준다는 것인데 직관적이지 않기 때문에 탈락!

  • 보면 전체적으로 @ResponseBody가 없기 때문에 view resolver가 view를 찾아서 렌더링하고있다.
    그리고 만약 @ResponseBody가 명시되어있다면 그냥 body에 'response/hello' 예시처럼 경로를 적어서 보내면 된다.

HTTP 메시지

@ResponseBody , HttpEntity 를 사용하면, 뷰 템플릿을 사용하는 것이 아니라, HTTP 메시지 바디에 직접 응답
데이터를 출력할 수 있다.

thymeleaf

  • 나중에 다시 포스팅하겠지만 일단 가볍게 적고가자면 타임리프를 추가하면 스프링 부트가 자동으로 ThymeleafViewResolver 와 필요한 스프링 빈들을 등록한다. 그리고 앞서도 언급했듯 prefix와 suffix를 설정해주는 이 설정은 기본 값 이기 때문에 변경이 필요할 때만 설정하면 된다.

  • 더 자세한 옵션들은 공식 문서를 보면 된다.

HTTP API

  • 메시지 바디에 직접 입력하여 응답,
    사실 앞에 req에서 했던 건데 다시 한 번 정리해보자.

문자열을 반환

reponse.getWriter

@GetMapping("/response-body-string-v1")
public void responseBodyV1(HttpServletResponse response) throws IOException
{
    response.getWriter().write("ok");
}

HttpEntity, ResponseEntity

/**
 * HttpEntity, ResponseEntity(Http Status 추가)
 * @return
 */
@GetMapping("/response-body-string-v2")
public ResponseEntity<String> responseBodyV2() {
    return new ResponseEntity<>("ok", HttpStatus.OK);
}
  • 이때 상태코드를 지정할 수 있음

@ResponseBody

@ResponseBody
@GetMapping("/response-body-string-v3")
public String responseBodyV3() {
    return "ok";
}
  • @ReponseBody 사용하여 메시지 컨버터를 통해 반환타입이 String임에도 view가 아니라 바디에 들어가도록 설정
    이건 ReponseEntity도 마찬가지임.

json을 반환

ResponseEntity

@GetMapping("/response-body-json-v1")
public ResponseEntity<HelloData> responseBodyJsonV1() {
    HelloData helloData = new HelloData();
    helloData.setUsername("userA");
    helloData.setAge(20);
    return new ResponseEntity<>(helloData, HttpStatus.OK);
}

@ResponseBody + ResponseStatus

@ResponseStatus(HttpStatus.OK)
@ResponseBody
@GetMapping("/response-body-json-v2")
public HelloData responseBodyJsonV2() {
    HelloData helloData = new HelloData();
    helloData.setUsername("userA");
    helloData.setAge(20);
    return helloData;
}
  • @ResponseBody 어노테이션을 붙이면 귀찮게 ResponseEntity를 추가하여 제네릭 타입을 안 잡아줘도 된다. 다만 이렇게 되면 상태 코드를 응답할 수 없기에
    @ResponseStatus 어노테이션을 추가하여 상태코드를 잡아줄 수 있다.

  • 다만 단점은 동적으로 반환이 안 되서 동적으로 상태코드를 응답하고 싶다면 ResponseEntity를 사용해야한다.

@RestController

  • @Controller 대신에 @RestController 애노테이션을 사용하면, 해당 컨트롤러에 모두 @ResponseBody 가 적용되는 효과가 있다. 따라서 뷰 템플릿을 사용하는 것이 아니라, HTTP 메시지 바디에 직접 데이터를 입력한다.

  • 참고로 @ResponseBody 는 클래스 레벨에 두면 전체 메서드에 적용되는데, @RestController 에노테이션 안에 @ResponseBody 가 적용되어 있다.

  • 그래서 아래는 @RestController와 함께 개발자가 가장 많이 사용하는 방식이다.

@ResponseStatus(HttpStatus.OK)
@GetMapping("/response-body-json-v2")
public HelloData responseBodyJsonV2() {
    HelloData helloData = new HelloData();
    helloData.setUsername("userA");
    helloData.setAge(20);
    return helloData;
}
profile
智(지)! 德(덕)! 體(체)!

0개의 댓글