Home Spring MVC - HTTP 요청 기본 기능
Post
Cancel

Spring MVC - HTTP 요청 기본 기능

HTTP 요청 - 기본

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
@RequestMapping("/hello-basic")
public String helloBasic() {
  log.info("MappingController.helloBasic");
  return "ok";
}

@RequestMapping(value = "/mapping-get-v1", method = RequestMethod.GET)
public String mappingGetV1() {
  log.info("MappingController.mappingGetV1");
  return "ok";
}

@GetMapping("/mapping-get-v2")
public String mappingGetV2() {
  log.info("MappingController.mappingGetV2");
  return "ok";
}

@GetMapping("/mapping/{userId}")
public String mappinPathV1(@PathVariable("userId") String data) {
  log.info("mappinPathV1 userId={}", data);
  return "ok";
}

@GetMapping("/mapping/{userId}")
public String mappinPathV2(@PathVariable String userId) {
  log.info("mappinPathV2 userId={}", userId);
  return "ok";
}

@GetMapping("/mapping/users/{userId}/orders/{orderId}")
public String mappinPathV3(@PathVariable String userId, @PathVariable Long orderId) {
  log.info("mappinPathV3 userId={} orderId={}", userId, orderId);
  return "ok";
}

// mode=debug 이라는 파라미터 문자열이 있어야 호출
@GetMapping(value = "/mapping-param", params = "mode=debug")
public String mappingParam() {
  log.info("mappingParam");
  return "ok";
}

// HTTP header에 mode=debug 값이 있어야 호출
@GetMapping(value = "/mapping-header", headers = "mode=debug")
public String mappingHeader() {
    log.info("mappingHeader");
    return "ok";
}

// HTTP header에 Content-Type 이 application/json 이어야 호출
@PostMapping(value = "/mapping-consume", consumes = "application/json")
public String mappingConsumes() {
    log.info("mappingConsumes");
    return "ok";
}

// HTTP header에 Accept 가 text/html 이어야 호출
@PostMapping(value = "/mapping-produce", produces = "text/html")
public String mappingProduces() {
    log.info("mappingProduces");
    return "ok";
}

HTTP 요청 - 헤더 조회

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
@RequestMapping("/headers")
public String headers(HttpServletRequest req,
                      HttpServletResponse resp,
                      HttpMethod httpMethod,
                      Locale locale,
                      @RequestHeader MultiValueMap<String, String> headerMap,
                      @RequestHeader("host") String host,
                      @CookieValue(value = "myCookie", required = false) String cookie) {
    log.info("request={}", req);
    log.info("response={}", resp);
    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, @RequestParam

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
@RequestMapping("/request-mapping")
public void requestParamV1(HttpServletRequest req, HttpServletResponse resp) throws IOException {
  String username = req.getParameter("username");
  int age = Integer.parseInt(req.getParameter("age"));
  log.info("username={}, age={}", username, age);

  resp.getWriter().write("ok");
}

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

@ResponseBody
@RequestMapping("/request-mapping-v3")
public String requestParamV3(@RequestParam String username, @RequestParam int age) {
  log.info("username={}, age={}", username, age);
  return "ok";
}

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

// 파라미터 필수 여부
// 필수 값이 true일때 해당 파라미터가 없는 요청이면 Bad Request 에러 반환
// 필수 값이 false 일때 해당 파라미터가 없는 요청이면 해당 변수는 null로 넘어옴
@ResponseBody
@RequestMapping("/request-param-requeired")
public String requestParamRequired(
  @RequestParam(required = true) String username,
  @RequestParam(required = false) Integer age) {
  log.info("username={}, age={}", username, age);
  return "ok";
}

// 파라미터 기본값 설정
@ResponseBody
@RequestMapping("/request-param-defult")
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";
}

// 파라미터를 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";
}

HTTP 요청 파라미터 - @ModelAttribute

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
// @ModelAttribute 사용시 각 필드의 getter, setter 필요
@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());
  return "ok";
}

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

HTTP 요청 메세지 - 단순 텍스트

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
@PostMapping("/request-body-string-v1")
public void requestBodyStringV1(HttpServletRequest res, HttpServletResponse resp) throws IOException {
  ServletInputStream inputStream = res.getInputStream();
  String messageBody = StreamUtils.copyToString(inputStream, StandardCharsets.UTF_8);
  log.info("messageBody={}", messageBody);

  resp.getWriter().write("ok");
}

/**
 * InputStream(Reader): HTTP 요청 메시지 바디의 내용을 직접 조회
 * OutputStream(Writer): HTTP 응답 메시지의 바디에 직접 결과 출력
 */
@PostMapping("/request-body-string-v2")
public void requestBodyStringV2(InputStream inputStream, Writer responseWriter) throws IOException {
  String messageBody = StreamUtils.copyToString(inputStream, StandardCharsets.UTF_8);
  log.info("messageBody={}", messageBody);

  responseWriter.write("ok");
}

/**
 * HttpEntity: HTTP header, body 정보를 편리하게 조회
 * - 메시지 바디 정보를 직접 조회(@RequestParam X, @ModelAttribute X)
 * - HttpMessageConverter 사용 -> StringHttpMessageConverter 적용
 *
 * 응답에서도 HttpEntity 사용 가능
 * - 메시지 바디 정보 직접 반환(view 조회X)
 * - HttpMessageConverter 사용 -> StringHttpMessageConverter 적용
 */
@PostMapping("/request-body-string-v3")
public HttpEntity<String> requestBodyStringV3(HttpEntity<String> httpEntity) {
  String messageBody = httpEntity.getBody();
  log.info("messageBody={}", messageBody);
  return new HttpEntity<>("ok");
}

/**
 * @RequestBody
 * - 메시지 바디 정보를 직접 조회(@RequestParam X, @ModelAttribute X)
 * - HttpMessageConverter 사용 -> StringHttpMessageConverter 적용
 *
 * @ResponseBody
 * - 메시지 바디 정보 직접 반환(view 조회X)
 * - HttpMessageConverter 사용 -> StringHttpMessageConverter 적용
 */
@ResponseBody
@PostMapping("/request-body-string-v4")
public String requestBodyStringV4(@RequestBody String messageBody) {
  log.info("messageBody={}", messageBody);
  return "ok";
}

HTTP 요청 메세지 - JSON

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
@Data
public class HelloData {
  private String username;
  private int age;
}

...

@Slf4j
@Controller
public class RequestBodyJsonController {

  private ObjectMapper objectMapper = new ObjectMapper();

  /**
   * {"username":"hello", "age":20}
   * content-type: application/json
   */
  @PostMapping("/request-body-json-v1")
  public void requestBodyJsonV1(HttpServletRequest req, HttpServletResponse resp) throws IOException {
    ServletInputStream inputStream = req.getInputStream();
    String messageBody = StreamUtils.copyToString(inputStream, StandardCharsets.UTF_8);

    log.info("messageBody={}", messageBody);
    HelloData data = objectMapper.readValue(messageBody, HelloData.class);
    log.info("username={}, age={}", data.getUsername(), data.getAge());

    resp.getWriter().write("ok");
  }

  /**
   * @RequestBody
   * HttpMessageConverter 사용 -> StringHttpMessageConverter 적용
   *
   * @ResponseBody
   * - 모든 메서드에 @ResponseBody 적용
   * - 메시지 바디 정보 직접 반환(view 조회X)
   * - HttpMessageConverter 사용 -> StringHttpMessageConverter 적용
   */
  @ResponseBody
  @PostMapping("/request-body-json-v2")
  public String requestBodyJsonV2(@RequestBody String messageBody) throws IOException {
    log.info("messageBody={}", messageBody);
    HelloData data = objectMapper.readValue(messageBody, HelloData.class);
    log.info("username={}, age={}", data.getUsername(), data.getAge());
    return "ok";
  }

  /**
   * @RequestBody 생략 불가능(@ModelAttribute 가 적용되어 버림)
   * HttpMessageConverter 사용 -> MappingJackson2HttpMessageConverter (content-
   * type: application/json)
  */
  @ResponseBody
  @PostMapping("/request-body-json-v3")
  public String requestBodyJsonV3(@RequestBody HelloData data) {
    log.info("username={}, age={}", data.getUsername(), data.getAge());
    return "ok";
  }

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

  /**
   * @RequestBody 생략 불가능(@ModelAttribute 가 적용되어 버림)
   * HttpMessageConverter 사용 -> MappingJackson2HttpMessageConverter (content-
     type: application/json)
  *
  * @ResponseBody 적용
  * - 메시지 바디 정보 직접 반환(view 조회X)
  * - HttpMessageConverter 사용 -> MappingJackson2HttpMessageConverter 적용
      (Accept: application/json)
  */
  @ResponseBody
  @PostMapping("/request-body-json-v5")
  public HelloData requestBodyJsonV5(@RequestBody HelloData data) {
    log.info("username={}, age={}", data.getUsername(), data.getAge());
    return data;
  }
}

HTTP 요청시에 header의 content-type이 application/json 이여야 json을 처리할 수 있는 HTTP 메세지 컨버터가 실행 됨


참고

  • 스프링 MVC - 백엔드 웹 개발 핵심 기술(김영한)
This post is licensed under CC BY 4.0 by the author.