스프링 MVC

HTTP 요청 처리 REQUEST

notx2wice 2021. 10. 28. 12:45

http 요청(클라이언트->서버)은 크게 3가지이다.

서버에서 클라이언트가 보낸 데이터를 어떻게 받나?

1. GET + queryparam

https://imnkj.tistory.com/134?category=804121

이런 url이 있으면 ?뒤의 부분으로 정보를 보내는 것이다.

2. POST + html form

http message body에 content-type: application/x-www-form-urlencoded 양식으로 정보를 보낸다.

1번과 양식이 같기 때문에 같은 방법으로 데이터를 서버에서 받을 수 있다 아래 코드를 참조 하자

@ResponseBody // ->이거 원래 스트링으로 리턴 하면 뷰리졸버에서 찾는데 이거쓰면 @Restcontroller처럼 동작하게 해줌
    @RequestMapping("/request-param") //@Restcontroller = @Controler + @Responsebody
    public String requestParam(
            @RequestParam("username") String memberName,
            @RequestParam("age") int memberAge) {

        log.info("username={}, age={}", memberName, memberAge);
        return "ok";
    }

정석적인 방법 근데 귀찮기 때문에 아래를 많이 쓴다.

    @ResponseBody // 파람 변수명이랑 맞추면 위에서 아래로 생략가능 바디에 집어 넣어 주나봄
    @RequestMapping("/request-param-v3")
    public String requestParamV3(
            @RequestParam String username,
            @RequestParam int age) {

        log.info("username={}, age={}", username, age);
        return "ok";
    }

    @ResponseBody
    @RequestMapping("/request-param-v4") // 단순 타입일 경우에만 생략가능
    public String requestParamV4(String username, int age) {
        log.info("username={}, age={}", username, age);
        return "ok";
    }

@RequestParam 까지도 생략가능 근데 이것까지는 쓰는게 시인성이 좋을 것 같다.

근데... 받을게 많은 경우는 ...?

1. 맵으로 받기

    @ResponseBody
    @RequestMapping("/request-param-map")
    public String requestParamMap(@RequestParam Map<String, Object> paramMap) {
        //키 밸류 1대1 map 1대n MultiValueMap
        log.info("username={}, age={}", paramMap.get("username"), paramMap.get("age"));
        return "ok";
    }

2. 모델을 만들어서 받기

/**
 * @Data 에 포함되어 있는 lombok은 다음과 같다.
 *
 * @ToString
 * @EqualsAndHashCode
 * @Getter : 모든 필드
 * @Setter : 정적 필드가 아닌 모든 필드
 * @RequiredArgsConstructor
 * @Data와 함께 포함되어 있는 lombok의 설정 예를 들어, callSuper, includeFieldNames 그리고 exclude 등을 지정할 수는 없다.
 *
 * 따라서 개별 어노테이션의 설정 값을 기본값이 아닌 값을 사용할 때에는 @Data 대신 개별 어노테이션을 사용하도록 한다.
 */
@Data
public class HelloData {
    private String username;
    private int age;
}

위는 모델 정의 아래는 사용법

    @ResponseBody
    @RequestMapping("/model-attribute-v1") //
    public String modelAttributeV1(@ModelAttribute HelloData helloData) {
        log.info("username={}, age={}", helloData.getUsername(), helloData.getAge());
        log.info("helloData = {}", helloData); // 이러면 알아서 투스트링도 해줌
        return "ok";
    }

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

3. 마지막으로 http message body에 데이터를 보내는 경우가 있다. post

-> 내용물이 String인 경우

    @PostMapping("/request-body-string-v3")
    public HttpEntity<String> requestBodyStringV3(HttpEntity<String> httpEntity) throws IOException {

        String messageBody = httpEntity.getBody();
        log.info("messageBody={}", messageBody);

        return new HttpEntity<>("ok");
    }

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

-> 내용물이  json인 경우

    @ResponseBody
    @PostMapping("/request-body-json-v3")
    public String requestBodyJsonV3(@RequestBody HelloData data) {
        log.info("username={}, age={}", data.getUsername(), data.getAge());
        return "ok";
    } 
    /**
     @Requestbody를 생략하면 @ModelAttribute가 적용됨
    */

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

    @ResponseBody
    @PostMapping("/request-body-json-v5")
    public HelloData requestBodyJsonV5(@RequestBody HelloData data) {
        log.info("username={}, age={}", data.getUsername(), data.getAge());
        return data; //결과는 json이 뿌려짐
        //requestbody json -> http 메세지 컨버터 -> 객체
        //response body -> 객체 -> 컨버터 -> json
    }

별첨 http 헤더를 뜯어 보고 싶은 경우

@Slf4j
@RestController
public class RequestHeaderController {

    @RequestMapping("/headers")
    public String headers(HttpServletRequest request,
                          HttpServletRequest 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";
    }
   
//정보들을 불러올수 있음 아래 처럼
//2021-10-28 12:50:47.661  INFO 50855 --- [nio-8080-exec-1] h.s.b.request.RequestHeaderController    : request=org.apache.catalina.connector.RequestFacade@f187619
//2021-10-28 12:50:47.662  INFO 50855 --- [nio-8080-exec-1] h.s.b.request.RequestHeaderController    : response=org.apache.catalina.connector.RequestFacade@f187619
//2021-10-28 12:50:47.662  INFO 50855 --- [nio-8080-exec-1] h.s.b.request.RequestHeaderController    : httpMethod=GET
//2021-10-28 12:50:47.662  INFO 50855 --- [nio-8080-exec-1] h.s.b.request.RequestHeaderController    : locale=ko
//2021-10-28 12:50:47.662  INFO 50855 --- [nio-8080-exec-1] h.s.b.request.RequestHeaderController    : headerMap={host=[localhost:8080], connection=[keep-alive], sec-ch-ua=["Google Chrome";v="95", "Chromium";v="95", ";Not A Brand";v="99"], sec-ch-ua-mobile=[?0], sec-ch-ua-platform=["macOS"], upgrade-insecure-requests=[1], dnt=[1], user-agent=[Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/95.0.4638.54 Safari/537.36], accept=[text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9], sec-fetch-site=[same-origin], sec-fetch-mode=[navigate], sec-fetch-user=[?1], sec-fetch-dest=[document], referer=[http://localhost:8080/], accept-encoding=[gzip, deflate, br], accept-language=[ko,en-US;q=0.9,en;q=0.8,zh;q=0.7], cookie=[Idea-8951df62=5dc7eaf5-76ff-4181-b3fc-4f80a71a0021; JSESSIONID=A08D449CFBAB0211D591E013FE4CD9BB]}
//2021-10-28 12:50:47.662  INFO 50855 --- [nio-8080-exec-1] h.s.b.request.RequestHeaderController    : header host=localhost:8080
//2021-10-28 12:50:47.662  INFO 50855 --- [nio-8080-exec-1] h.s.b.request.RequestHeaderController    : myCookie=null
// multivaluemap으로 받으면 다 받아 올수 있음.
}

 

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

HTTP 응답 처리 RESPONSE  (0) 2021.10.28