스프링MVC

HTTP 요청 -기본, 헤더, 데이터 조회

salmon16 2023. 8. 22. 17:42

애노테이션 기반의 스프링 컨트롤러는 다양한 파라미터를 지원한다

HTTP 헤더 정보를 조회하는 방법을 알아보자

@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";
    }
}
  • HttpMethod : HTTP 메서드를 조회한다 
  • Locale : Locale 정보를 조회한다
  • @RequestHeader MultiValueMap<String, String> headerMap
    • 모든 HTTP 헤더를 MultiValueMap형식으로 조회한다.
  • @RequestHeader("host") String host
    • 특정 HTTP헤더를 조회한다 (host)
  • @CookieValue(value = "myCookie", required=false) String cookie
    • 특정 쿠키(myCookie)를 조회한다.

HTTP 요청 데이터 조회

클라이언트에서 서버로 요청 데이터를 전달할 때 주로 3가지 방법을 사용한다

1. GET- 쿼리 파라미터

2. POST- HTML Form

3. HTTP message body에 데이터를 직접 담아서 요청

 

하나씩 조회하는 방법을 알아보자

GET - 쿼리 파라미터, POST-HTML Form

1. HttpServletRequest, HttpServletResponse 사용

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

2. @RequestParm 애노테이션 사용

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

 

 

여기서 memberName -> username, memberAge -> age로 변수명을 변경 시 @RequestParam만 해줘도 된다.

 

3. @RequestParm 애노테이션 생략

@ResponseBody
@RequestMapping("/request-param-v4")
public String requestParamV4(String username,int age) {
    log.info("username={}, age={}", username, age);
    return "ok";
}

@RequestParm 애노테이션을 생략해도 되지만 권장하는 방법은 아니다.

 

4.required와 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";
}

필주적인 파라미터에는 required=true로 하면 된다 만약 이 파라미터가 없으면 에러가 발생한다

defaultValue는 아무 값이 들어오지 않을 때 자동으로 설정해 주는 값이다.

 

5. 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";
}

6. ModelAttribute를 사용

요청 파라미터를 받아서 필요한 객체를 만들고(new) 그 객체에 값을 setter를 사용해서 넣어주어야 한다

스프링에서 이 과정을 스프링에서 자동화 ModelAttribute를 사용하면 자동화해 준다

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

먼저 객체를 만든다 @Data는 @Getter, @Setter, @ToString, @EqualsAndHashCode, @RequriedArgsContructor를 자동으로 적용해 준다.

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

그리고 ModelAttribute를 사용하면 요청 파라미터의 값이 helloData안에 들어가 있다.

스프링은 @ModelAttribute가 있으면 객체를 생성하고 요청 파라미터 이름으로 객체의 프로퍼티를 찾아 setter를 호출해서 파라미터의 값을 바인딩해 준다.

 

@ModelAttribute 애노테이션도 생략이 가능하지만 혼란이 발생할 수 있으므로 권장하지 않는다.

 

HTTP mesaage body

요청 파라미터와 다르게 HTTP 메시지 바디를 통해 데이터가 직접 넘어오는 경우 @RequestParam, @ModelAttribute를 사용할 수 없다.

 

단순 텍스트를 받아보자

1. HttpEntity 사용

@PostMapping("/request-body-string-v3")
public HttpEntity<String> requestBodyStringV3(HttpEntity<String> httpEntity) {
    String messageBody = httpEntity.getBody();
    log.info("messageBody={}", messageBody);
    return new HttpEntity<>("ok");
}

HttpEntity는 HTTP header, body 정보를 편리하게 조회한다

HttpMessageConverter을 사용한다 

응답에서도 HttpEntity를 사용 가능하다.

메시지 바디 정보를 직접 반환한다. 

 

HttpEntity를 상속받은 다음 객체들도 같은 기능을 제공한다.

RequestEntitiy : HttpMethod, url정보 추가, 요청에서 사용

ResponseEntity : HTTP 상태 코드 설정 가능, 응답에서 사용

return new ResponseEntity<String>("Hello", responseHeaders, HttpStatus.CREATED)

 

2.RequestBody, ResponseBody사용

@ResponseBody
@PostMapping("/request-body-string-v4")
public String requestBodyStringV4(@RequestBody String messageBody) {
    log.info("messageBody={}", messageBody);
    return "ok";
}

@ResponseBody를 사용하면 응답 결과를 HTTP 메시지 바디에 직접 담아서 전달할 수 있다.

@RequestBody를 사용하면 HTTP메시지 바디 정보를 편리하게 조회할 수 있다

헤더 정보가 필요하다면 HttpEntity를 사용하거나 @RequestHeader을 사용하면 된다.

 

단순 텍스트가 아닌 JSON데이터 형식을 조회해 보자.

 

1.RequestBody, ResponseBody 객체 파라미터

@ResponseBody
@PostMapping("/request-body-json-v5")
public HelloData requestBodyJsonV5(@RequestBody HelloData data) {
    log.info("username={}, age={}", data.getUsername(), data.getAge());
    return data;
}

@RequestBody에 직접 만든 객체를 지정할 수 있다.

@RequestBody는 생략이 불가능하다.

@ResponseBody를 사용해서 HTTP메시지 바디에 객체를 직접 넣어줄 수 있다.

2.HttpEntity 사용

@ResponseBody
@PostMapping("/request-body-json-v4")
public String requestBodyJsonV4(HttpEntity<HelloData> httpEntity) {
    HelloData data = httpEntity.getBody();
    log.info("username={}, age={}", data.getUsername(), data.getAge());
    return "ok";
}

HttpEntity를 사용해도 된다.

 

HttpEntity, @RequestBody를 사용하면 HTTP 메시지 컨버터가 HTTP 메시지 바디의 내요을 우리가 원하는 문자나 객체, JSON 등으로 변환해 준다.

 

출처 : 스프링MVC 1편 - 백엔드 웹 개발 핵심 기술 김영한

'스프링MVC' 카테고리의 다른 글

HTTP 메시지 컨버터  (0) 2023.08.23
HTTP 응답 - 정적 리소스, 뷰 템플릿  (0) 2023.08.23
스프링 MVC 기본 기능  (0) 2023.08.21
로깅 간단하게 알아보기  (0) 2023.08.18
스프링 MVC 시작하기  (0) 2023.08.10