스프링 공부 (인프런 김영한 선생님)/스프링 MVC 1편

[스프링 웹 MVC 1편] 22. HTTP 요청 파라미터 (@ModelAttribute, 단순 텍스트)

2023. 6. 3. 19:49

 

package hello.springmvc.basic;


import lombok.Data;

@Data // @Getter, @Setter, @ToString, @EqualsAndHashCode, @RequiredArgsConstructor 적용
public class HelloData {

    private String username;
    private int age;

}

실제 개발과정에 있어서는 다음과 같은 객체를 이용하는 경우가 많다.

보통 다음과 같은 과정을 통해 객체를 활용하고는 할텐데

이때 스프링 MVC는 이런 객체 활용에 있어 용이한 기능을 제공한다.

다음 코드를 자동화해준다고 생각하자

@RequestParam String username;
  @RequestParam int age;
  HelloData data = new HelloData();
  data.setUsername(username);
  data.setAge(age);

 

@ModelAttribute 애노테이션의 기능을 알아보겠다

 

다음 코드를 보자

package hello.springmvc.basic.request;

import hello.springmvc.basic.HelloData;
import java.io.IOException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;

@Slf4j
@Controller
public class RequestParamController {

   
    // JSON식 Response 생성법
    @ResponseBody
    @RequestMapping("/model-attribute-v1")
    public String modelAttributeV1(@RequestParam String username, @RequestParam int age){
        HelloData helloData = new HelloData();
        helloData.setUsername(username);
        helloData.setAge(age);

        log.info("helloData={}", helloData.toString());
        // 그냥 helloData하면 toString으로 출력됨.

        return "ok";
    }

    @ResponseBody
    @RequestMapping("/model-attribute-v2")
    public String modelAttributeV2(@ModelAttribute HelloData helloData){
        //HelloData helloData = new HelloData();
        //helloData.setUsername(username);
        //helloData.setAge(age);

        log.info("helloData={}", helloData.toString());
        // 그냥 helloData하면 toString으로 출력됨.

        return "ok";
    }

    @ResponseBody
    @RequestMapping("/model-attribute-v3")
    public String modelAttributeV3(HelloData helloData){
        //HelloData helloData = new HelloData();
        //helloData.setUsername(username);
        //helloData.setAge(age);

        log.info("helloData={}", helloData.toString());
        // 그냥 helloData하면 toString으로 출력됨.

        return "ok";
    }


}

modelAttributeV1을 보면, 메서드에 HelloData 타입의 파라미터를 주고, @ModelAttribute 애노테이션만 적용해줬는데도

위에 일일히 객체를 생성하고 setter를 적용해줘야했던것과는 다르게, 요청 파라미터의 값이 모두 설정되어있다.

 

@ModelAttribute는 다음과 같은 과정을 자동화한다.

1. HelloData 객체를 생성

2. RequestParameter의 이름으로 HelloData 객체의 프로퍼티(setter,getter)를 찾는다.

그리고 해당 프로퍼티의 setter를 호출해서 파라미터의 값을 바인딩한다.

 

age=abc처럼 숫자가 들어가야 할 곳에 문자를 넣으면 BindException이 발생하는데 이는 검증부분에서 다룬다.

 

modelAttributeV2는 애노테이션을 생략해도 적용되는 것을 보여준다.

다만, @RequestParam도 생략이 가능하기 때문에 Clarification이 필요하다.

 

스프링은 애노테이션 생략시 다음과 같은 기준으로 적용한다

1) String, int, Integer와 같은 단순 타입 = @RequestParam

2) 나머지 객체 타입(userdefined) = @ModelAttribute(argument resolver로 지정해둔 타입 외)


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

HTTP 메세지 바디에 데이터를 직접 담아서 요청할 때,

JSON, XML, 단순 텍스트가 오고 갈 수 있는데 데이터 형식은 주로 JSON을 사용한다 했다.

 

요청 파라미터와 다르게 HTTP 바디를 통해 메세지가 직접 넘어오는 경우

@RequestParam이나 @ModelAttribute를 사용할 수 없다.

 

package hello.springmvc.basic.request;

import java.io.IOException;
import java.io.InputStream;
import java.io.Writer;
import java.nio.charset.StandardCharsets;
import javax.servlet.ServletInputStream;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import lombok.extern.slf4j.Slf4j;
import org.springframework.http.HttpEntity;
import org.springframework.stereotype.Controller;
import org.springframework.util.StreamUtils;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;

@Slf4j
@Controller
public class RequestBodyStringController {

    @PostMapping("/request-body-string-v1")
    public void requestBodyString(HttpServletRequest request, HttpServletResponse response)
        throws IOException {
        ServletInputStream inputStream = request.getInputStream();
        String messageBody = StreamUtils.copyToString(inputStream, StandardCharsets.UTF_8);

        log.info("messageBody = {}", messageBody);

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

    @PostMapping("/request-body-string-v2")
    public void requestBodyStringV2(InputStream inputStream, Writer responseWriter)
        throws IOException {
        String messageBody = StreamUtils.copyToString(inputStream, StandardCharsets.UTF_8);
        log.info("messageBody={}", messageBody);
        responseWriter.write("ok");
    }

    @PostMapping("/request-body-string-v3")
    public HttpEntity<String> requestBodyStringV3(HttpEntity<String> httpEntity){
        String messageBody = httpEntity.getBody();
        log.info("messageBody={}", messageBody);
        return new HttpEntity<>("ok");
    }

    @PostMapping("/request-body-string-v4")
    public String requestBodyStringV4(@RequestBody String messageBody){
        log.info("messageBody = {}", messageBody);
        return "ok";
    }

}

1. requestBodyString

- Servlet에서 HTTP Body의 내용을 request의 getInputStream으로 파싱한 것과 같다.

이때 파싱을 위해 StreamUtils.copyToString을 사용해야하며 두번째 파라미터로 StandardCharsets.UTF-8을 넘겨주어야 한다는 것을 잊지 말자.

 

2. requestBodyStringV2

스프링 MVC는 다음 파라미터를 지원한다

- InputStream(Reader) : HTTP 요청 메세지 바디의 내용을 직접 조회

- OutputStream(Writer) : HTTP 응답 메세지의 바디에 직접 결과 출력

 

3. requestBodyStringV3

HttpEntity: HTTP header, Body 정보를 편리하게 조회함 -> HTTP 메세지를 스펙화 한 객체

요청 파라미터를 조회하는 기능과 관계 없음, @RequestParam, @ModelAttribute와 관계 X

Get의 쿼리스트링 Form Post, content-type : www-x-urlencoded외에는 직접 데이터 꺼내야 함.

 

HttpEntity는 응답에도 사용 가능

-> 메세지 바디 정보 직접 반환

-> 헤더 정보 포함 가능

-> view 조회 X

 

HttpEntity를 상속 받은 다음 객체들도 같은 기능을 제공한다

-> RequestEntity : HttpMethod, url 정보가 추가 / 요청에서 사용한다

-> ResponseEntity : Http 상태 코드 설정 가능, 응답에서 사용

return new ResponseEntity<String>("Hello World", responseHeaders, HttpStatus.CREATED)

 

4. requestBodyStringV4

@RequestBody를 사용하면 HTTP 메세지 바디 정보를 편리하게 조회함.

헤더 정보가 필요하다면, HttpEntity를 사용하거나 @RequestHeader를 사용하면 된다.

 

메세지 바디를 직접 조회하는 기능은 요청 파라미터를 조회하는 @RequestParam, @ModelAttribute와는 상관 없다

 

요청 파라미터 vs HTTP 메세지 바디

- > 요청 파라미터를 조회하는 기능 : @RequestParam, @ModelAttribute

- > HTTP 메세지 바디를 직접 조회하는 기능 : @RequestBody

 

@ResponseBody를 사용하면 응답 결과를 HTTP 바디에 직접 담아서 전달할 수 있는데, 이때도 뷰 사용 X

 

'스프링 공부 (인프런 김영한 선생님) > 스프링 MVC 1편' 카테고리의 다른 글

[스프링 웹 MVC 1편] 24. HTTP 응답 - 정적 리소스, 뷰 템플릿  (0) 2023.06.04
[스프링 웹 MVC 1편] 23. HTTP 요청 파라미터 (JSON)  (0) 2023.06.03
[스프링 웹 MVC 1편] 21. 스프링 MVC - 기본기능 (기본/헤더/쿼리파라미터/ HTML Form 조회)  (1) 2023.06.03
[스프링 웹 MVC 1편] 20. 스프링 MVC - 기본기능 (요청매핑)  (0) 2023.06.03
[스프링 웹 MVC 1편] 19. 스프링 MVC - 기본 기능 (로깅)  (0) 2023.06.01
'스프링 공부 (인프런 김영한 선생님)/스프링 MVC 1편' 카테고리의 다른 글
  • [스프링 웹 MVC 1편] 24. HTTP 응답 - 정적 리소스, 뷰 템플릿
  • [스프링 웹 MVC 1편] 23. HTTP 요청 파라미터 (JSON)
  • [스프링 웹 MVC 1편] 21. 스프링 MVC - 기본기능 (기본/헤더/쿼리파라미터/ HTML Form 조회)
  • [스프링 웹 MVC 1편] 20. 스프링 MVC - 기본기능 (요청매핑)
ProgYun.
ProgYun.
인내, 일관성, 그리고 꾸준함을 담습니다.
ProgYun.
Perseverance, Consistency, Continuity
ProgYun.
전체
오늘
어제
  • 분류 전체보기
    • 칼럼
    • 일상생활
      • 월별 회고
      • 인생 이야기 (대학생활)
      • 취준
      • 운동인증
      • 제품 사용 후기와 추천
    • 스프링 공부 (인프런 김영한 선생님)
      • 스프링 핵심원리
      • 스프링 MVC 1편
      • 스프링 MVC 2편
    • 면접 준비
    • 전공
      • OOP 정리
      • Design Pattern
    • 스터디
    • English
      • Electronics(Laptop)
      • 1일 1단어

블로그 메뉴

  • 홈
  • 태그
  • 방명록

공지사항

인기 글

태그

  • 자존감
  • 윈도우재설치
  • 확진자
  • 자가격리
  • 코로나19
  • 해외직구
  • 대학생
  • 오미크론
  • 하이닉스
  • 윈도우10
  • 코로나
  • p31
  • 컴공
  • ssd
  • 편입생
  • 포맷
  • 일상
  • NVME
  • mason
  • 피로그래밍

최근 댓글

최근 글

hELLO · Designed By 정상우.
ProgYun.
[스프링 웹 MVC 1편] 22. HTTP 요청 파라미터 (@ModelAttribute, 단순 텍스트)
상단으로

티스토리툴바

개인정보

  • 티스토리 홈
  • 포럼
  • 로그인

단축키

내 블로그

내 블로그 - 관리자 홈 전환
Q
Q
새 글 쓰기
W
W

블로그 게시글

글 수정 (권한 있는 경우)
E
E
댓글 영역으로 이동
C
C

모든 영역

이 페이지의 URL 복사
S
S
맨 위로 이동
T
T
티스토리 홈 이동
H
H
단축키 안내
Shift + /
⇧ + /

* 단축키는 한글/영문 대소문자로 이용 가능하며, 티스토리 기본 도메인에서만 동작합니다.