Web/MVC

EP6. HTTP 요청 데이터 처리

Http 헤더 꺼내기


docs.spring.io/spring-framework/docs/current/reference/html/web.html#mvc-annarguments

 

Web on Servlet Stack

Spring Web MVC is the original web framework built on the Servlet API and has been included in the Spring Framework from the very beginning. The formal name, “Spring Web MVC,” comes from the name of its source module (spring-webmvc), but it is more com

docs.spring.io

위 주소에서 Controller의 Parameter로 받을 수 있는 것들이 무엇이 있는지 나와있다.

 

 

 

예시 코드

package hello.springmvc.basic.request;

import lombok.extern.slf4j.Slf4j;
import org.springframework.http.HttpMethod;
import org.springframework.util.MultiValueMap;
import org.springframework.web.bind.annotation.CookieValue;
import org.springframework.web.bind.annotation.RequestHeader;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.Locale;

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

    }
}

 

 

 

 

Http 요청 파라미터 (쿼리 파라미터, HTML Form) 꺼내기


GET 방식 쿼리 파라미터

ex) http://localhost:8080/request-param?username=hello&age=20

 

POST 방식 HTML Form

ex)

POST /request-param ... 
content-type: application/x-www-form-urlencoded 
username=hello&age=20

 

위 두 방식은 둘다 형식이 같아서 같은 방식으로 조회가 가능하다.

 

 

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

	// version 3 파라미터 변수의 이름과 같으면 생략이 가능하다.
    @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로 필수 파라미터를 지정할 수 있다.

    @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 일때 null 은 안되지만 "" (빈값) 은 된다.
  • required = false 이고 int 타입을 받을 때 null이 안된다. int 는 null을 받을 수 없기 때문에 이 경우에는 Integer 타입으로 받아야한다.

 

default 값을 지정할 수 있다.

    @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이고 ""(빈문자)를 줄때도 default 값으로 세팅한다.

 

 

 

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

 

 

 

@ModelAttribute

실무에서는 보통 객체로 데이터를 넘긴다.

객체에 값을 세팅하는 과정을 스프링이 자동화 해준다.

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

 

심지어 @ModelAttribute 도 생략 가능하다.

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

 


스프링은 @RequestParam과 @ModelAttribute 의 생략을 어떻게 찾아낼까?

스프링은 생략시 다음과 같은 규칙을 적용한다.

  • String, int, Integer 같은 단순 타입 : @RequestParam
  • 나머지 : @ModelAttribute (argument resolver로 지정해둔 타입 외)

 

 

 

 

 

 

 

 

 

Http 요청 메세지 바디 데이터


@RequestBody 를 사용한다

 

Http Body에 단순 TEXT 요청, 응답

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

@RequestBody로 바디의 데이터를 가져오고

@ReponseBody 애노테이션을 사용해서 String을 반환하면 바디에 적힌다.

 

 

 

Http Body에 Json 요청, 응답

    // Json 요청, Text 응답
    @ResponseBody
    @PostMapping("/request-body-json-v3")
    public String requestBodyJsonV3(@RequestBody HelloData helloData){
        log.info("username = {}, age = {}", helloData.getUsername(), helloData.getAge());
        return "ok";
    }
    
    // Json 요청, Json 응답
    @ResponseBody
    @PostMapping("/request-body-json-v5")
    public HelloData requestBodyJsonV5(@RequestBody HelloData data){
        log.info("username = {}, age = {}", data.getUsername(), data.getAge());
        return data;
    }

@RequestBody 애노테이션을 주고 Json 요청을 받을 객체로 받아온다.

만약 Json 으로 반환하고싶을 경우에는 객체를 그대로 반환하면 된다.

(스프링이 자동으로 Object Mapper를 호출해서 Json으로 바꿔준다.)

 

 

주의점

@RequestBody 생략하면 안된다. 생략할 시 @ModelAttribute로 적용된다.

 

 

 

Http 요청 데이터 처리하기 정리


  • 요청 파라미터를 조회하는 기능 : @RequestParam, @ModelAttribute
  • HTTP 메세지 바디를 직접 조회하는 기능 : @RequestBody

'Web > MVC' 카테고리의 다른 글

EP8. Thymeleaf 타임리프  (0) 2021.04.01
EP7. HTTP 응답 데이터 처리  (0) 2021.03.30
EP5. Spring MVC 기본 기능 (요청 매핑)  (0) 2021.03.25
EP4. 스프링 MVC 구조  (0) 2021.03.25
EP4. MVC 패턴  (0) 2021.03.22