HTTP 요청 메시지를 통해 클라이언트에서 서버로 데이터를 전달하는 방법에 대해 공부해보자.
클라이언트에서 서버로 요청 데이터를 전달할 때 주로 사용하는 3가지 방법
GET - 쿼리 파라미터
- /example?username=son&age=25
- 메시지 바디없이, URL의 쿼리 파라미터에 데이터를 포함해서 전달
- 검색, 필터, 페이징등에서 많이 사용
POST - HTML Form
- content-type : application/x-www-form-urlencoded
- 메시지 바디에 쿼리 파라미터 형식으로 전달 username=son&age=20
- 회원 가입, 상품 주문, HTML Form 사용
HTTP message body에 데이터를 직접 담아서 요청
- HTTP API에서 주로 사용, JSON / XML / TEXT
- 주로 JSON
- POST, PUT, PATCH
쿼리 파라미터, HTML Form
HttpServletRequest의 request.getParameter()를 사용하면 두가지 요청(쿼리 파라미터, HTML Form) 파라미터를 조회 가능
둘다 형식이 같으므로 구분없이 조회할 수 있다. 이를 간단히 요청 파라미터 조회라 한다.
쿼리 파라미터를 통해 넘어온 값이 로그로 찍힌 것을 확인할 수 있다.
이번에는 POST 방식의 HTML Form을 사용하여 데이터를 전송해보자
해당 url로 접속 후 데이터를 전송하면
역시 마찬가지로 request.getParameter를 통해 조회되어 로그로 출력되었다.
@RequestParam
스프링이 제공하는 @RequestParam을 사용하면 요청 파라미터를 매우 편리하게 사용할 수 있다.
@RequestParam
- 파라미터 이름으로 바인딩
@ResponseBody
- 현재 해당 컨트롤러가 @RestController가 아닌 @Controller로 되어 있기때문에 위와 같이 String을 반환하면 해당하는 ViewName을 찾게 되는데 @ResponseBody를 사용하면 이를 무시하고 HTTP message body에 해당 내용을 넣어준다.(쉽게 말해 @RestController를 사용했을 때와 같은 효과)
추가로 쿼리 파라미터의 키와 변수명을 맞추면 아래와 같이 더 간단하게 작성 가능(PathVariable처럼)
심지어 아래와 같이 아예 @RequestParam이라는 애노테이션까지 빼고 사용가능
쿼리 파라미터의 키와 변수명을 맞추고, String, int, Integer 등의 단순 타입이라면
파라미터 필수 여부
@RequestParam의 required 속성을 통해 해당 파라미터가 필수 값인지 여부를 설정할 수 있다.
- username은 필수 값
- age는 필수 값이 아님
- 기본 값은 true
Interger는 객체이기 때문에 null 값이 들어갈 수 있으나, int(기본형)는 null값을 받을 수 없음.
만약 Int age로 선언된 상태에서 위와 같은 url로 접속했다면 오류가 발생함
마찬가지로 String에도 null 값을 넣을 수 없다.
하지만 "/~~?username=" 과 같은 url로 접속하면 username에 null 값이 들어가는 것이 아니라 공백문자로 인식되어 오류가 발생하지 않음
기본 값 적용
값이 들어오지 않았을 때의 기본값을 설정해줄 수 있다.
- default 값을 설정해주었기 때문에 Interger가 아닌 기본형 int를 사용할 수 있음
defaultValue는 앞서 언급한 공백 문자로 처리해준다.
파라미터 Map으로 조회
모든 요청 파라미터를 Map에 담아 해당하는 key값으로 꺼내 사용할 수 있다.(MultiValueMap도 가능)
파라미터의 값이 1개가 확실하다면 Map을 사용하지만 그렇지 않다면 MultiValueMap을 사용
@ModelAttribute
요청 파라미터를 받아 필요한 객체 예를 들어 user라는 객체를 만들고, 그 객체에 값을 넣어주어야 한다.
@RequestParam String username;
@RequestParam int age;
User user = new User();
user.setName(username);
user.serAge(age);
대략 위와 같은 코드로 객체를 만들고 값을 넣어줄 것인데,
Spring은 이 과정을 자동화해주는 @ModelAttribute를 제공한다.
먼저 요청 파라미터를 받을 객체 클래스를 생성
롬복의 @Data
- @Getter, @Setter, @ToString, @EqualsAndHashCode, @RequiredArgsConstructor을 자동으로 적용해준다.
- @RequiredArgsConstructor : final이나 @NonNull 인 필드 값만 파라미터로 받는 생성자를 만들어 준다.
- @EqualsAndHashCode : equals와 hashCode 자동 생성
- equals : 두 객체의 내용이 같은지, 동등성(equality) 를 비교하는 연산자
- hashCode : 두 객체가 같은 객체인지, 동일성(identity) 를 비교하는 연산자
스프링 MVC는 @ModelAttribute가 있으면 다음을 실행한다.
- 해당 객체를 생성(HelloData)
- 요청 파라미터의 이름으로 HelloData 객체의 프로퍼티를 찾는다.
- 해당 프로퍼티의 setter를 호출해 파라미터의 값을 입력(바인딩)한다.
프로퍼티란 getter / setter 를 통해 관리되는 데이터를 칭한다.
getUsername이라는 메서드가 있으면 get를 떼고 첫글자를 소문자로 바꾼 name을 프로퍼티 name으로 취급한다. 즉, 이 객체는 username이라는 프로퍼티를 가지고 있는 것이다.
숫자가 들어가야할 age에 age=minchul과 같이 문자를 넣으면 BindException(바인딩 오류)가 발생함.
@ModelAttribute 생략
@ModelAttribute는 생략이 가능하다.(@RequestParam도 생략가능하니 주의)
스프링은 위와 같은 생략시 다음 규칙을 적용한다.
- String, int, Integer 같은 단순 타입 = @RequestParam
- 나머지 = @ModelAttribute (argument resolver 로 지정해둔 타입 이외)
반응형
'Spring > Spring MVC' 카테고리의 다른 글
HTTP Response (0) | 2021.05.10 |
---|---|
HTTP Request Message (0) | 2021.05.09 |
HTTP 요청 - 헤더 정보 (0) | 2021.05.07 |
요청 매핑 (0) | 2021.05.06 |
로깅 간단히 알아보기 (0) | 2021.05.03 |