초보 개발자의 성장기

genieus와 함께하는 Spring 요청 파라미터 알아보기 본문

BackEnd 지식

genieus와 함께하는 Spring 요청 파라미터 알아보기

개발자 김케빈 2021. 12. 20. 14:58

이번 포스팅은 요청 파라미터에 대해서 작성하려고 합니다!

이번 글을 보시면 Client와 Server가 어떻게 소통하는 지 알 수 있는 좋은 기회가 되실거라고 확신합니다!


 

Client에서 서버로 요청 데이터를 전달하는 방법

GET, 쿼리 파라미터 전송

메시지 body 없이 URL의 쿼리 파라미터에 데이터를 포함해서 전달
ex) /url?id=bts&name=amy

POST, HTML form

메시지 body에 쿼리 파라미터 형식으로 전달
ex) id=kim123&name=kim

HTTP message body

데이터에 직접 담아서 요청, HTTP API에서 주로 사용 (JSON, XML, TEXT) 데이터 형식은 주로 JSON 형식을 많이 사용합니다.

 

@RequestBody

RequestBody 어노테이션은 Json 형태의 HTTP Body의 내용을 Java Object로 변환시켜주는 역할을 수행

주로 비동기 처리를 할 때 많이 사용합니다. 

 

✭ 비동기 처리 : 특정 코드의 연산이 끝날 때 까지 코드의 실행을 멈추지 않고 다음 코드를 먼저 실행하는 특성


@RequestBody는 Body의 내용이 들어오지 않으면 사용할 수 없음 --> GET 방식에서는 에러가 발생하고 POST 방식에서만 가능!!

@RequestBody로 받는 데이터는 Spring에서 관리하는 MessageConverter들을 통해 Java 객체로 변환됩니다.

 

✭ MessageConverter : 자바 객체와 HTTP 요청 / 응답 body를 변환시키는 역할. 메서드와 컨트롤러에 @RequestBody를 명시할
경우 파라미터 타입에 맞는
converter를 선택한 다음 HTTP 요청 본문 통째로 메시지로 변환한 후 리턴하거나 파라미터에 바인딩


Header에서 명시해준 Content-type에 맞는 MessageConver를 사용하여 요청 본문에 담긴 데이터를 자바 객체로 변환

Spring은 메세지를 변환되는 과정에서 객체의 기본 생성자를 통해 객체를 생성하고, 내부적으로 Reflection을 사용해 값을 할당하므로 @RequestBody에는 값을 주입하기 위한 생성자나 Setter가 필요 없다.

 

 

@RequestParam

RequestParam 어노테이션 1개의 HTTP 요청 파라미터(url에서 찾음)를 받기 위해서 사용한다.

GET 방식으로 넘어온 URI queryString을 받기 적절하다.

@RequestParam이 붙여진 인자의 타입이 String이 아닌 경우 Type Conversion이 자동으로 적용된다. (사용자 정의 가능)
@RequestParam String 아닐 경우 Object 변경 해주는건 Formatter도 아니고 Converter도 아니고 DataBinder이다.

@ControllerAdvice
public class BindingControllerAdvice {

    @InitBinder
    public void initBinder(WebDataBinder binder) {
        binder.initDirectFieldAccess();
    }

}

다음의 코드를 컨트롤러 내부에 위치시키면 DataBinder Reflection 사용해서 필드에 직접 Access 있도록 만들어줍니다.

 

@RequestParam은 필수 여부가 true이기 때문에 기본적으로 반드시 해당 파라미터가 전송되어야 합니다.
해당 파라미터가 전송되지 않으면 400 Error를 유발하게 됩니다.
그렇기 때문에 반드시 필요한 변수가 아니라면 
required의 값을 false로 설정해둘 수 있으며
해당 Parameter를 사용하지 않고 요청을 보낼 경우에 default로 받을 값을
defaultValue 옵션을 통해 설정할 수도 있습니다.

파라미터를 Map이나 MultiValueMap으로 조회할 수 있습니다.

만약, 파라미터가 2개 이상이면 MultiValueMap 사용

또한, 변수 명과 요청 파라미터 명이 같으면 RequestParam 생략가능

Ex) @RequestParam("age") int age <=> @RequestParam int age


비동기식으로 데이터를 전달할 때는 url은 변함이 없고 body에 데이터를 포함하여 전송하기 때문에
@RequestParam
으로는 받을 수 없습니다.

  @RequestBody @RequestParam
메서드 파라미터명 설정 필요없음 설정 필요함
객체 생성 가능 불가능
변수별로 데이터 저장 불가능 가능

 

PathVariable

http://127.0.0.1/index/1와 같은 형식의 URL에서 (RestAPI) 값을 호출할 때 주로 사용.

==> url 경로에 변수를 넣어줌

 - PathVariable127.0.0.1:8080/abcd/abcd와 같이 경로에 값을 넣어주지만

 - RequestParam은 127.0.0.1:8080?a=b&c=d url 파라미터로 변수를 넘겨 줍니다.

 

ModelAttribute

@ModelAttribute는 클라이언트가 전송하는 multipart/form-data 형태의 HTTP Body 내용과 HTTP 파라미터의 값들을
생성자나 Setter를 통해 주입(
스프링이 자동화)하기 위해 사용됩니다.
@ModelAttribute
에는 매핑시키는 파라미터의 타입이 객체의 타입과 일치하는지를 포함한 다양한 검증(Validiation) 작업이 추가적으로 진행됩니다.

만약 번호를 저장하는 int형 index 변수에 "1번" 이라는 String형을 넣으려고 한다면, BindException이 발생하게 된다.

, Json이나 XML과 같은 형태의 데이터를 MessageConverter를 통해 변환시키는 @RequestBody와 달리,

@ModelAttribute multipart/form-data 형태의 HTTP Body HTTP 파라미터들을
생성자나 수정자로 주입시킨다는 차이가 있다.

Comments