[F-Lab] 모각코 챌린지 9일차

tree·2023년 5월 10일
0

HTTP 요청 파라미터 - @ModelAttribute

  • @ModelAttribute

    • GET 요청의 요청 파라미터나 POST 요청의 메시지 바디의 내용을 받아서 객체로 변환시켜준다.
    • 변환된 객체를 모델에 추가해준다.
    @Data
    class HelloData {
      private String username;
      private int age;
    }
    
    /**
    * @ModelAttribute 사용
    * 참고: model.addAttribute(helloData) 코드도 함께 자동 적용됨, 뒤에 model을 설  명할 때 자세히 설명
    */
    @ResponseBody
    @RequestMapping("/model-attribute-v1")
    public String modelAttributeV1(@ModelAttribute HelloData helloData) {
      return "ok";
    }
    • HelloData 객체를 생성하여 요청 파라미터 이름으로 HelloData 객체의 프로퍼티를 찾는다. 그리고 해당 프로퍼티의 setter를 호출해 값을 입력한다.
    • 그리고 model.addAttribute(클래스명의 앞글자를 소문자로 바꾼 문자열, 객체)도 같이 호출한다.
  • 프로퍼티

    • 객체에 getUsername(), setUsername() 메서드가 있으면, 이 객체는 username이라는 프로퍼티가 있다고 말한다.
  • @ModelAttribute 생략

    /**
    * @ModelAttribute 생략 가능
    * String, int 같은 단순 타입 = @RequestParam
    * argument resolver 로 지정해둔 타입 외 = @ModelAttribute
    */
    @ResponseBody
    @RequestMapping("/model-attribute-v2")
    public String modelAttributeV2(HelloData helloData) {
      return "ok";
    }
    • @ModelAttribute는 생략 가능하지만 @RequestParam도 생략이 가능해 혼란 발생.
      • String, int같은 단순 타입 -> @RequestParam 적용
      • 나머지 -> @ModelAttribute 적용(argument resolver로 지정한 타입 제외)
  • @ModelAttribute의 다른 기능

    • 메소드 레벨에 @ModelAttribute을 붙히면 해당 컨트롤러 요청 시 @ModelAttribute를 호출해 메소드의 리턴 값을 Model에 추가.

HTTP 요청 메시지 - 단순 텍스트

  • 기존에는 HTTP 메시지 바디의 내용을 꺼낼 때, HttpServletRequest 객체의 getInputStream()을 사용해 꺼냈었다.

  • 하지만 스프링에서는 더욱 간편하게 메시지 바디의 내용을 꺼낼 수 있다.

  • Input, Output 스트림, Reader

    /**
    * InputStream(Reader): HTTP 요청 메시지 바디의 내용을 직접 조회
    * OutputStream(Writer): HTTP 응답 메시지의 바디에 직접 결과 출력
    */
    @PostMapping("/request-body-string-v2")
    public void requestBodyStringV2(InputStream inputStream, Writer responseWriter) throws IOException {
      String messageBody = StreamUtils.copyToString(inputStream, StandardCharsets.UTF_8);
      responseWriter.write("ok");
    }
    • HttpServletRequest를 사용하는 것과 비슷하다.
    • 잘 사용하지는 않는다.
  • HttpEntity

    /**
    * HttpEntity: HTTP header, body 정보를 편리하게 조회
    * - 메시지 바디 정보를 직접 조회(@RequestParam X, @ModelAttribute X)
    * - HttpMessageConverter 사용 -> StringHttpMessageConverter 적용
    *
    * 응답에서도 HttpEntity 사용 가능
    * - 메시지 바디 정보 직접 반환(view 조회X)
    * - HttpMessageConverter 사용 -> StringHttpMessageConverter 적용
    */
    @PostMapping("/request-body-string-v3")
    public HttpEntity<String> requestBodyStringV3(HttpEntity<String> httpEntity) {
      String messageBody = httpEntity.getBody();
      return new HttpEntity<>("ok");
    }
    • HttpEntity
      • HTTP header, body 정보를 편리하게 조회.
      • 요청 파라미터를 조회하는 기능과 관계 없음.
      • 응답에도 사용 가능
        • 메시지 바디 정보 직접 반환
        • 헤더 정보 포함 가능
        • view 조회X
      • HttpEntity 를 상속받은 RequestEntity, ResponseEntity도 같은 기능 제공.
        • RequestEntity
          • HttpMethod, url 정보가 추가
          • 요청에서 사용
        • ResponseEntity
          • HTTP 상태 코드 설정 가능
          • 응답에서 사용
  • @RequestBody

    /**
    * @RequestBody
    * - 메시지 바디 정보를 직접 조회(@RequestParam X, @ModelAttribute X)
    * - HttpMessageConverter 사용 -> StringHttpMessageConverter 적용
    *
    * @ResponseBody
    * - 메시지 바디 정보 직접 반환(view 조회X)
    * - HttpMessageConverter 사용 -> StringHttpMessageConverter 적용
    */
    @ResponseBody
    @PostMapping("/request-body-string-v4")
    public String requestBodyStringV4(@RequestBody String messageBody) {
      return "ok";
    }
    • @RequestBody 를 사용하면 HTTP 메시지 바디 정보를 편리하게 조회
      • 헤더 정보가 필요하다면 HttpEntity를 사용하거나 @RequestHeader를 사용하면 된다.
    • @ResponseBody
      • 응답 결과를 HTTP 메시지 바디에 직접 담을 수 있다.
  • 요청 파라미터 vs HTTP 메시지 바디

    • 요청 파라미터 조회
      • @RequestParam , @ModelAttribute
    • HTTP 메시지 바디 직접 조회
      • @RequestBody

HTTP 요청 메시지 - JSON

  • 서블릿을 사용할 때는 HttpServletRequest의 getInputStream()을 이용해 메시지 바디의 내용(JSON)을 꺼내서 ObjectMapper를 이용해 객체로 변환했다.

  • 스프링에서는 더 간편하게 JSON을 객체로 변환할 수 있다.

  • @RequestBody 객체 변환

    /**
    * @RequestBody 생략 불가능(@ModelAttribute가 적용되어 버림)
    * HttpMessageConverter 사용 -> MappingJackson2HttpMessageConverter (contenttype: application/json)
    */
    @ResponseBody
    @PostMapping("/request-body-json-v3")
    public String requestBodyJsonV3(@RequestBody HelloData data) {
      return "ok";
    }
    • HttpEntity , @RequestBody를 사용하면 HTTP 메시지 컨버터가 HTTP 메시지 바디의 내용을 우리가 원하는 문자나 객체 등으로 변환해준다.
    • HTTP 메시지 컨버터는 문자 뿐만 아니라 JSON도 객체로 변환.
    • @RequestBody는 생략 불가능
      • @RequestBody를 생략하면 @ModelAttribute가 적용되어버린다.
  • HttpEntity

    @ResponseBody
    @PostMapping("/request-body-json-v4")
    public String requestBodyJsonV4(HttpEntity<HelloData> httpEntity) {
      HelloData data = httpEntity.getBody();
      return "ok";
    }
    • HttpEntity를 사용해도 된다.
  • @ResponseBody

    /**
    * @RequestBody 생략 불가능(@ModelAttribute 가 적용되어 버림)
    * HttpMessageConverter 사용 -> MappingJackson2HttpMessageConverter (contenttype: application/json)
    *
    * @ResponseBody 적용
    * - 메시지 바디 정보 직접 반환(view 조회X)
    * - HttpMessageConverter 사용 -> MappingJackson2HttpMessageConverter 적용 (Accept: application/json)
    */
    @ResponseBody
    @PostMapping("/request-body-json-v5")
    public HelloData requestBodyJsonV5(@RequestBody HelloData data) {
      return data;
    }
    • 응답의 경우에도 @ResponseBody 를 사용하면 해당 객체를 HTTP 메시지 바디에 직접 넣어줄 수 있다.

    • @RequestBody 요청

      • JSON 요청 -> HTTP 메시지 컨버터 -> 객체
    • @ResponseBody 응답

      • 객체 -> HTTP 메시지 컨버터 -> JSON 응답

0개의 댓글