HTTP body에 데이터를 실어서 전송하기

hee·2023년 8월 11일
0
post-custom-banner

먼저, http header의 Content-Type 이해가 필요하다.

Content-Type

  1. 한 사람이 바구니에 쌀을 들고 창고로 이동 한다고 상상을 해보자. 창고에는 밀가루 / 보리 / 쌀로 구분해 나눠 넣는다.
  2. 쌀 자루를 들고와서 창고 지킴이에게 쌀을 건네주고 돌아간다.
  3. 그런데 지킴이는 바구니 안에 자루안에 뭔지 모른다? 자루를 뜯어 보며 구분을 해서 종류에 맞게 창고에 분류 해 넣는다.
  4. 그렇지만 계속 오는 사람들마다 자루를 열어서 확인을 해야하기 때문에 힘이 든다.
  5. 그래서 오는 사람은 어떤 종류의 곡식을 가져오는지 종이에 써서 같이 달라고 하게 된다. (안주면 다시 되돌려 보냄)

그리하여 문서에 작성해서 전송하는데, 그렇게 되면 두가지를 같이 보내는 것이다.(쌀, 쌀이 적힌 문서)
여기서 쌀 = body Data, 문서 = header
하지만 header에 '쌀’이라고만 적을 수 는 없다. 아래와같이 작성한다.

무게(양) : 1kg
종류 : 쌀
원산지 : 진주

이 header 문서 안에 Content Type이 들어있고 Content Type이 쌀이라고 적어준다.
Body data를 전송할 때 Content Type을 명시해서 전달해야 받는 쪽에서 일을 수월하게 할 수 있게 되는 것이다.
그래서 Content Type은 http header에 프로토콜로 존재한다.(=HTTP Protocol)
다만, Post와 Put 요청을 할 때만..!
Delete와 get은 body 데이터가 없기때문에 content Type도 필요 X

데이터가 들어오는 타입(Content Type) 종류는 대표적으로 아래와 같다.

  • x-www-form-urlencoded (형태 : key=value)
  • text/plain (형태 : 안녕>문자 그대로)
  • application/json (형태 : {"username":"cos"}
  • 그밖에 이미지, 동영상 파일 등등..
    스프링부트는 기본적으로 데이터를 들고오면 x-www-form-urlencoded으로 인식을 하고 타입을 파싱(분석)한다.

각 content Type은 형태가 다르기 때문에 데이터를 날릴 때 꼭, content Type에 각각 유형을 명시 해줘야 창고지킴이(스프링부트)가 해석 할 수 있다.


post요청이기 때문에 postman을 사용한다.

@RestController
public class HttpBodyController {
	
	@PostMapping("/body1")
	public String xwwwformurlencoded() {
		return "key=value 전송옴";
		
	}
	@PostMapping("/body2")
	public String textplain() { //평문
		return "plain/text 전송옴";
		
	}
	@PostMapping("/body3")
	public String applicationjson() {
		return "json 전송옴";
	}
}

x-www-form-urlencoded

1 과 같이 POST요청으로 경로를 설정해주고 send를 눌러보면 return값이 출력되는것을 볼 수 있다.
2 와 같이 body를 체크하고 x-www-form-urlencoded 체크한 후에
KEY, VALUE를 입력하고 다시 한번 send를 눌러주면 똑같이 return 값이 출력된다.

Content Type이 제대로 되었는지 확인은 아래와 같이 Headers - Hidden을 눌러보면 Conten-Type - application/x-www-form-urlencoded이 되어있는것을 확인 할 수 있다.(send를 누르기 전에는 Content Type 항목이 없다.)

Body에 전송한 값을 보기 위해서는 매세드에 매개변수를 지정해준다. 데이터를 확인하기 위해서 Logger라이브러리를 사용한다.(직접 Logger 객체를 생성해서 logging하는 방법)

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;


@RestController
public class HttpBodyController {

private static final Logger log = LoggerFactory.getLogger(HttpBodyController.class);

	@PostMapping("/body1")
	public String xwwwformurlencoded(String username) {
		log.info(username);
		return "key=value 전송옴";
		
	}
}


username(Key값)의 Value값인 cos가 출력된다. 변수타입과 변수 이름(String username)만 매개변수에 넣어줬는데 데이터가 받아와지는 이유는 x-www-form-urlencoded 타입을 파싱(분석)해주기 때문이다. 해당 변수명이 body의 key값과 다르면 데이터를 받아오지 못한다.

text/plain

	@PostMapping("/body2")
	public String textplain(@RequestBody String data) { //평문
		log.info(data);
		return "plain/text 전송옴";
		
	}

매개변수명은 data로 입력한다.
text/plain은 key값이 없어서 @RequestBody 어노테이션을 걸어 데이터 그대로 받을 수 있게 해준다.

application/json

	@PostMapping("/body3")
	public String applicationjson(@RequestBody String data) {
		log.info(data);
		return "json 전송옴";
	}

application/json 타입도 key값이 없어서 @RequestBody 어노테이션을 걸어 데이터 그대로 받을 수 있게 해준다.

그런데 이 방식은 data.username를 호출하거나 cos값을 받아낼 수가 없다.

새로운 패키지를 만들고 그 안에 User.java파일을 만들어서 username를 만들어 주고 Getter, Setter를 적용시켜준다.(다른 자바 파일에서도 사용할 수 있게 하기 = 모델링)

package com.cos.controller_demo.domain;

public class User {
	private String username;

	public String getUsername() {
		return username;
	}

	public void setUsername(String username) {
		this.username = username;
	}
	
}


package com.cos.controller_demo.web;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.context.annotation.RequestScope;

import com.cos.controller_demo.domain.User;

@RestController
public class HttpBodyController {
	
	private static final Logger log = LoggerFactory.getLogger(HttpBodyController.class);

	@PostMapping("/body1")
	public String xwwwformurlencoded(String username) {
		log.info(username);
		return "key=value 전송옴";
		
	}
	@PostMapping("/body2")
	public String textplain(@RequestBody String data) { //평문
		log.info(data);
		return "plain/text 전송옴";
		
	}
	@PostMapping("/body3")
	public String applicationjson(@RequestBody String data) {
		log.info(data);
		return "json 전송옴";
	}
	@PostMapping("/body4")
	public String applicationjsonToObject(@RequestBody User user) {
		log.info(user.getUsername());
		return "json 전송옴";
	}
}
profile
고군분투 코린이의 코딩일기
post-custom-banner

1개의 댓글

comment-user-thumbnail
2023년 8월 11일

글 재미있게 봤습니다.

답글 달기