스프링 HTTP 요청 - 쿼리 파라미터
클라이언트에서 서버로 요청 데이터를 전달하는 방법은 주로 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= 역시 공백문자가 있는 것으로, 정상 출력된다.
필수 파라미터(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 생략 가능)