기본, 헤더 조회
애노테이션 기반의 스프링 컨트롤러는 다양한 파라미터를 지원한다. 고로 이전에 사용했던 HttpServletRequest, HttpServletResponse 등 다양한 객체를 사용할 수 있다.
@Slf4j
@RestController
public class RequestHeaderController {
@RequestMapping("/headers")
public String headers(HttpServletRequest request,
HttpServletResponse response,
HttpMethod httpMethod,
Locale locale,
@RequestHeader MultiValueMap<String, String> headerMap,
@RequestHeader("host") String host,
@CookieValue(value = "myCookie", required = false) String cookie) {
log.info("request={}", request);
log.info("response={}", response);
log.info("httpMethod={}", httpMethod);
log.info("locale={}", locale);
log.info("headerMap={}", headerMap);
log.info("header host={}", host);
log.info("myCookie={}", cookie);
return "ok";
}
}
- Locale : Locale 정보를 조회
- @RequestHeader MultiValueMap<String, String>
- 모든 HTTP 헤더를 MultiValueMap 형식으로 조회한다.
- Map과 유사한데, 하나의 키에 여러 값을 받을 수 있다.
- HTTP header, HTTP 쿼리 파라미터와 같이 하나의 키에 여러 값을 받을 때 사용한다.
- @RequestHeader("host")
- 특정 HTTP 헤더를 조회한다. 속성으로는 필수 값 여부인 required, 기본 값 속성인 defaultValue가 존재함
- @CookieValue(value ="myCookie", required = false)
- 특정 쿠키를 조회한다. 필수 값 여부인 required, 기본 값 속성인 defaultValue가 존재함
@Slf4j 어노테이션을 활용하면 아래의 코드를 자동으로 생성하여 로그를 선언해준다. 개발자는 log로 사용이 가능하다.
private static final org.slf4j.Logger log =
org.slf4j.LoggerFactory.getLogger(RequestHeaderController.class);
쿼리 파라미터, HTML Form 방식
쿼리 파라미터의 Get방식, HTML Form에서 넘어오는 POST 방식의 경우에는 간단히 HttpServletRequest가 제공하는 getParameter() 메서드를 사용해 조회할 수 있다.
@Slf4j
@Controller
public class RequestParamController {
@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");
}
}
@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) 속성이 파라미터 이름으로 사용된다.
즉, 이는 request.getParameter("username")
과 같다.
해당 메서드에 @ResponseBody 어노테이션을 붙이면, 클래스 단위에서 @RestController를 붙인것 과 같이 HTTP message body에 직접 해당 내용을 입력한다.
참고로 아래와 같이 HTTP 파라미터 이름이 변수 이름과 같으면 생략이 가능하다.
@ResponseBody
@RequestMapping("/request-param-v3")
public String requestParamV3(
@RequestParam String username,
@RequestParam int age
) {
log.info("username={}, age={}", username, age);
return "ok";
}
더 나아가, @RequestParam 자체를 생략할 수도있는데, 이는 명확성이 떨어져 보이므로 팀과 협의가 된 상태에서 사용하는 것을 추천.
@ResponseBody
@RequestMapping("/request-param-v4")
public String requestParamV4(
String username,
int age
) {
log.info("username={}, age={}", username, age);
return "ok";
}
required, 필수값 설정
그리고 @RequestParam에는 필수값을 설정할 수도있다. 기본값(true) @RequestParam(required = true)
@RequestParam 어노테이션을 생략하는 경우 required=false를 적용한다.
@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";
}
위와같은 코드에서는
/request-param-required : username
이 없으므로 400 예외/request-param-required?username=
: 빈문자로 통과
여기에서 age를 Integer로 설정한 이유는 int는 기본형이므로 null이 들어갈 수 없기 때문이다.
defaultValue
위의 상황은 @RequestParam의 defaultValue
설정을 통해 해결할 수 있다.
@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";
}
이 경우에는 빈문자열이 들어와도, defaultValue인 guest로 설정된다. 그리고 age가 들어오지 않더라도 기본값이 -1로 설정되어 있기 때문에 500예외가 발생하지 않는다.
파라미터의 값이 1개가 확질하지 않은 경우, MultiValueMap을 통해 조회할 수 있다.
@ResponseBody
@RequestMapping("/request-param-map")
public String requestParamDefault(@RequestParam Map<String, Object> paramMap) {
log.info("username={}, age={}", paramMap.get("username"), paramMap.get("age"));
return "ok";
}
@ModelAttribute
실제 개발시에는 요청 파라미터를 받아 필요한 객체를 만들고 그 객체에 값을 넣어주어야한다.
@ResponseBody
@RequestMapping("/model-attribute-v1")
public String modelAttributeV1(@RequestParam String username, @RequestParam int age) {
HelloData helloData = new HelloData();
helloData.setUsername(username);
helloData.setAge(age);
log.info("username={}, age={}", helloData.getUsername(), helloData.getAge());
return "ok";
}
하지만 @ModelAttribute를 사용하여 이를 간략하게 작성할 수 있다.
@ResponseBody
@RequestMapping("/model-attribute-v2")
public String modelAttributeV2(@ModelAttribute HelloData helloData) {
log.info("username={}, age={}", helloData.getUsername(), helloData.getAge());
return "ok";
}
대신 해당 코드는 바인딩 받을 객체가 필요하다.
package hello.springmvc.basic;
import lombok.Data;
@Data
public class HelloData {
private String username;
private int age;
}
Lombok의 @Data 어노테이션은 @Getter, @Setter, @ToString, @EqualsAndHashCode, @RequiredArgsConstructor를 자동으로 적용해준다.
@ModelAttribute 어노테이션이 있는 경우 스프링 MVC가 아래의 과정을 거친다.
- 객체생성
- 요청 파라미터의 이름으로 객체의 프로퍼티를 찾음.
- 해당 프로퍼티의 setter를 호출하여 파라미터의 값을 바인딩
@ModelAttribute도 아래와 같이 생략이 가능하다
@ResponseBody
@RequestMapping("/model-attribute-v2")
public String modelAttributeV2(HelloData helloData) {
log.info("username={}, age={}", helloData.getUsername(), helloData.getAge());
return "ok";
}
위 글은 김영한 스프링 MVC 1편 - 백엔드 웹 개발 핵심 기술의 일부 내용을 정리한 것입니다.
'Backend > Spring' 카테고리의 다른 글
[Spring] 스프링 MVC 1편 - 백엔드 웹 개발 핵심 기술 #5 스프링 MVC 기본 기능 - HTTP 요청 메시지 / 단순 텍스트 및 JSON (0) | 2024.08.22 |
---|---|
[Spring] 스프링 MVC 1편 - 백엔드 웹 개발 핵심 기술 #5 스프링 MVC 기본 기능 - 요청 매핑 (0) | 2024.08.05 |
[Spring] 스프링 MVC 1편 - 백엔드 웹 개발 핵심 기술 #5 스프링 MVC 기본 기능 - 프로젝트 생성, 로깅 (0) | 2024.07.31 |
[Spring] 스프링 MVC 1편 - 백엔드 웹 개발 핵심 기술 #5 스프링 MVC 구조 이해 (0) | 2024.07.30 |
[Spring] 스프링 MVC 1편 - 백엔드 웹 개발 핵심 기술 #4 MVC 프레임워크 (0) | 2024.07.10 |