FreeHand

스프링 HTTP 요청 - 쿼리 파라미터 본문

Web/Spring

스프링 HTTP 요청 - 쿼리 파라미터

Jinn 2023. 10. 29. 09:04

클라이언트에서 서버로 요청 데이터를 전달하는 방법은 주로 3가지이다.

 

GET - 쿼리 파라미터

  • ?name=Jin&age=25
  • 메시지 바디 없이 URL의 쿼리 파라미터에 데이터를 포함해서 전달한다.
  • 검색, 필터, 페이징 등에서 많이 사용하는 방식이다.

POST - HTML Form

  • content-type: application/x-www-form-urlencoded
  • 메시지 바디에 쿼리 파라미터 형식으로 데이터를 전달한다.
  • 회원 가입, 상품 주문 등에서 사용한다.

HTTP message body

  • 메시지 바디에 직접 데이터를 담아서 전달한다.
  • 데이터 형식은 JSON, XML, TEXT 등. 주로 JSON 형식을 사용한다.

 

GET 쿼리 파라미터, POST HTML Form

@Slf4j
@Controller
public class RequestParamController {

 /**
 * 반환 타입이 없으면서 이렇게 응답에 값을 직접 집어넣으면, view 조회X
 */
    @RequestMapping("/request-param-v1")
    public void requestParamV1(HttpServletRequest request, HttpServletResponse response) throws IOException {
        String username = request.getParameter("username");
        int age = Integer.parseInt(request.getParameter("age"));
        log.info("username={}, age={}", username, age);
        
        response.getWriter().write("ok");
    }
}

@Controller 애노테이션이 사용되었지만 반환 타입이 void이고 응답에 값을 직접 넣으면 뷰를 찾지 않는다.

서블릿에서 쿼리 파라미터를 조회하는 request.getParameter()를 사용해서 조회한다.

 

@ResponseBody
@RequestMapping("/request-param-v3")
public String requestParamV3(@RequestParam("username") String memberName,
                             @RequestParam("age") int memberAge) {
    log.info("username={}, age={}", memberName, memberAge);
    return "ok";
}

@ResponseBody 를 사용하면 반환 타입이 있어도 뷰를 찾지 않고 HTTP 메시지 바디에 내용을 입력한다.

@RequestParam 을 사용해서 쿼리 파라미터를 조회할 수 있다.

public String requestParamV3(@RequestParam String username, @RequestParam int age) {
    log.info("username={}, age={}", username, age);
    return "ok";
}

쿼리 파라미터의 key와 변수명이 일치하면 위처럼 생략 가능하다.

 

public String requestParamV3(String username, int age) {
    log.info("username={}, age={}", username, age);
    return "ok";
}

String, int, Integer 등 단순 타입이면 @RequestParam도 생략할 수 있다.

 

파라미터의 필수 여부도 설정할 수 있다.

@Slf4j
@Controller
public class RequestParamcontroller {

    @ResponseBody
    @RequestMapping("/request-param-required")
    public String requestParamRequired(@RequestParam(required = true) String username,
                                       @RequestParam(required = false) Integer age) {
        log.info("username={}, age={}", username, age);
        return "ok";
    }
}

정상적으로 출력됨

required = true이면 해당 파라미터가 반드시 있어야 한다.

?username= 역시 공백문자가 있는 것으로, 정상 출력된다.

400 Bad Request

필수 파라미터(username)가 없으면 클라이언트 오류가 발생한다.

 

반대로 required = false이면 해당 파라미터가 없어도 된다.

이때 age에는 null이 들어가는데 int 타입은 null을 담을 수 없으므로 Integer 타입으로 선언해야 한다.

 

@ResponseBody
@RequestMapping("/request-param-default")
public String requestParamDefault(@RequestParam(required = true, defaultValue = "jin") String username,
                                  @RequestParam(required = false, defaultValue = "25") int age) {
    log.info("username={}, age={}", username, age);
    return "ok";
}

defaultValue 속성으로 값이 파라미터가 입력되지 않았을 때 기본값을 설정할 수 있다. (+ 공백문자일때)

기본값을 설정할 경우 required 속성은 사실상 의미 없게 된다.

이 경우에는 null이 들어갈 일이 없으므로 기본형(int) 타입을 사용해도 된다.

정상 출력

 

파라미터를 Map과 MultiValueMap으로 조회할 수 있다.

@ResponseBody
@RequestMapping("/request-param-map")
public String requestParamMap(@RequestParam Map<String, Object> paramMap) {
    log.info("username={}, age={}", paramMap.get("username"), paramMap.get("age"));
    return "ok";
}

key = [value1, value2, ...] 처럼 값이 여러개이면 MultiValueMap을 사용한다.

 

 

@ModelAttribute를 사용할 수도 있다.

@Data
public class HelloData {
    private String username;
    private int age;
}

요청 파라미터를 바인딩 받을 객체를 만들었다.

롬복의 @Data를 사용하면 @Getter, @Setter, @ToString, @EqualsAndHashCode, @RequiredArgsConstructor를 자동으로 적용한다.

 

@ResponseBody
@RequestMapping("/model-attribute-v1")
public String modelAttributeV1(@ModelAttribute HelloData helloData) {
    log.info("username={}, age={}", helloData.getUsername(), helloData.getAge());
    return "ok";
}

스프링MVC는 @ModelAttribute가 있으면 다음처럼 동작한다.

1. HelloData객체를 생성한다.

2. 요청 파라미터 이름으로 HelloData 객체의 프로퍼티를 찾는다. 해당 프로퍼티의 setter를 호출해서 파라미터 값을 바인딩(입력)한다.

 

아래 코드와 같은 일을 @ModelAttribute가 자동으로 해주는 것이다.

HelloData data = new HelloData();
data.setUsername(username);
data.setAge(age);

 

@ModelAttribute는 생략 가능하다.

@ResponseBody
@RequestMapping("/model-attribute-v2")
public String modelAttributeV2(HelloData helloData) {
    log.info("username={}, age={}", helloData.getUsername(), helloData.getAge());
    return "ok";
}

String, int 같은 단순 타입만 있으면 @RequestParam이 생략된 것이고,

그 외에는 @ModelAttribute가 생략된 것이다.(argument resolver로 지정한 타입 제외)

 

요청 파라미터를 아무것도 입력하지 않았을 때 String은 null, int는 0이 들어갔다.

 

 

요약

쿼리 파라미터를 조회하는 방법

?username=jin

  • request.getParameter("username")
  • @RequestParam String username (@RequestParam 생략 가능), (Map으로 조회 가능)
  • @ModelAttribute HelloData helloData (@ModelAttribute 생략 가능)

 

 

스프링 MVC 1편 - 백엔드 웹 개발 핵심 기술 - 인프런 | 강의 (inflearn.com)

'Web > Spring' 카테고리의 다른 글

스프링 HTTP 응답  (0) 2023.11.19
스프링 HTTP 요청 - 메시지 바디(JSON, TEXT)  (0) 2023.11.04
HTTP 헤더 조회  (0) 2023.10.29
스프링 요청 매핑  (1) 2023.10.29
로깅  (1) 2023.10.28