프레임워크(Framework)/Spring

[Spring MVC] 스프링 MVC @RequestParam 사용 방법 정리

잇트루 2022. 11. 17. 08:41
반응형
본 내용은 온라인 강의 사이트 인프런의 김영한 님의 강의 내용이 포함되어 있습니다.
'스프링 MVC 1편 - 백엔드 웹 개발 핵심 기술'
 

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

웹 애플리케이션을 개발할 때 필요한 모든 웹 기술을 기초부터 이해하고, 완성할 수 있습니다. 스프링 MVC의 핵심 원리와 구조를 이해하고, 더 깊이있는 백엔드 개발자로 성장할 수 있습니다., -

www.inflearn.com

 

@RequestParam

스프링은 HTTP 요청 파라미터를 @RequestParam으로 받을 수 있다.

@RequestParam은 파라미터 이름으로 바인딩하는 방법이다.

스프링이 제공하는 @RequestParam을 사용하면 요청 파라미터를 매우 편리하게 사용할 수 있다.

만약 요청 파라미터에 username과 age가 있다고 가정한다.

 

예전 방식

@RequestMapping("/save")
public ModelAndView save(HttpServletRequest request, HttpServletResponse response) {
    String username = request.getParameter("username");
    int age = Integer.parseInt(request.getParameter("age"));
    ...
}

 

@RequestParam 사용

@PostMapping("/save")
public String save(@RequestParam("username") String username, @RequestParam("age") int age, Model model) {
    ...
}

HttpServletRequest과 HttpServletResponse을 파라미터로 받아 요청을 변환하고, ModelAndView로 반환하기까지의 불편한 로직이 상당 부분 해소되었다.

또한, Model 파라미터를 통해 내부 로직에 편의 기능을 제공받을 수 있다.

 

@RequestParam의 효율적인 사용

@RequestParam을 활용한 기본적인 예시이다.

@ResponseBody
@RequestMapping("/request-param-v2")
public String requestParamV2(@RequestParam("username") String memberName,
                             @RequestParam("age") int memberAge) {

    log.info("username={}, age={}", memberName, memberAge);

    return "ok";
}

위 방법은 @RequestParam의 name(value) 속성이 파라미터 이름으로 사용한다.

  • @RequestParam("username") String memberName의 경우
  • request.getParameter(”username”)으로 조회 가능

@ResponseBody : View 조회를 무시하고, HTTP message body에 직접적으로 응답한다.

 

위 코드를 아래와 같이 단순화할 수 있다.

@ResponseBody
@RequestMapping("/request-param-v3")
public String requestParamV3(@RequestParam String username,
                             @RequestParam int age) {

    log.info("username={}, age={}", username, age);

    return "ok";
}

HTTP 파라미터 이름이 변수의 이름과 같은 경우 ("username")과 같은 name 속성을 생략할 수 있다.

@RequestParam("username") String memberName → @RequestParam String username

 

뿐만 아니라, 아예 @RequestParam을 생략할 수도 있다.

@ResponseBody
@RequestMapping("/request-param-v4")
public String requestParamV4(String username, int age) {

    log.info("username={}, age={}", username, age);

    return "ok";
}

이는 모든 경우에서 생략 가능한 것은 아니다. String, int, Integer와 같은 단순 타입에서만 생략이 가능하다.

하지만, @RequestParam을 붙이는 것으로 요청 파라미터를 명확하게 표현하는 것도 좋은 방법이다.

 

@RequestParam 속성

name

파라미터의 이름을 지정하는 것으로 다른 속성이 없을 경우 “name = “은 생략이 가능하다.

@RequestParam(name = “username”)
@RequestParam(“age”)

 

required

파라미터의 필수 여부를 결정한다. 기본값으로 필수(true)이다.

required가 true일 때 해당 파라미터가 없으면 HTTP 상태 코드 400을 반환하며, false인 경우 해당 파라미터가 없어도 예외가 발생하지 않는다.

@RequestParam(name = “username”, required = true)
@RequestParam(name = “username”, required = false)
@ResponseBody
@RequestMapping("/request-param-required")
public String requestParamRequired(@RequestParam(required = true) String username,
                                   @RequestParam(required = false) int age) {

    log.info("username={}, age={}", username, age);

    return "ok";
}
  • username은 필수, age는 값이 없어도 상관없다.
  • username이 없는 경우 HTTP 상태 코드 400 예외가 발생한다.
  • age의 타입은 int 타입이며, int는 null 값을 허용하지 않는다.
  • 따라서 age가 없는 경우 HTTP 상태 코드 500 예외가 발생한다.

 

@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";
}
  • age의 타입을 Integer로 바꿔야 null값을 허용하게 된다.
  • 따라서 위 코드의 경우 age가 없어도 정상적으로 응답하게 된다.

 

주의할 점

  • “/request-param?username=” 요청
  • 파라미터의 이름만 있고 값이 없는 경우에는 빈문자로 취급하여 예외가 발생하지 않음
  • 값이 없는 null과 빈문자 “”는 서로 다른 개념이기 때문

 

defalutValue

파라미터에 값이 없는 경우 defaultValue 속성을 사용하여 기본 값을 적용할 수 있다.

이 경우 기본 값이 설정되어 있기 때문에 required와 함께 사용하더라도 required는 의미가 없어진다.

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

이 경우 required는 의미가 없어진다.

  • /request-param-default를 요청한 경우 username=guest, age=-1
  • /request-param-default?username=hello를 요청한 경우 username=hello, age=-1
  • /request-param-default?age=20을 요청한 경우 username=guest, age=20

 

추가적으로 username을 공백(“”)으로 전달하더라도 defaultValue인 guest로 적용된다.

  • /request-param-default?username=를 요청한 경우 username=guest, age=-1

 

파라미터를 Map으로 조회

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

@RequestParam Map<String, Object>

Map 사용

@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";
}

MultiValueMap은 파라미터의 값이 여러 개인 경우 사용할 수 있다.

  • /request-param-map?username=kim&username=park&…
  • username이 다수인 경우에도 응답할 수 있다.
  • 파라미터의 값이 1개가 확실하다면 Map을 사용해도 되지만, 그렇지 않은 경우 MultiValueMap을 사용해야 한다.
반응형