@PathVariable, @RequestParam 에 대하여
출처: https://woogienote.tistory.com/104
출처: https://ittrue.tistory.com/243
@PathVariable이란?
@RequestParam 이란?
@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을 사용해야 한다.
출처: https://ittrue.tistory.com/243 [IT is True:티스토리]