Wanna be Brilliant Full-Stack Developer

SpringBoot Blog만들기 http요청 실습2 본문

Back-End/블로그 만들기 With SpringBoot

SpringBoot Blog만들기 http요청 실습2

Flashpacker 2023. 2. 13. 01:48

 


이번에는 HTTP 요청 4가지 방식을 통해 요청시에 데이터를 어떻게 실어서 보내는지!

어떤 데이터를 요청하게 어떤 데이터를 수정하고, 어떤 데이터를 인서트하고 ,어떤 데이터를 삭제할 수 있는지

방법, HOW에 대해서 알아보려고 한다.

이걸 하기 위해서는 MODEL이 필요하다!

자바에서 변수는 Private로 만든다 왜냐하면 예를 들어 우리가 배고픔이라는 상태 값이 있다고 생각해보자

이렇게 People이라는 모델을 만들어서

50 정도 허기가 지는데 예를 들어 내가 만약에 배고픔을 해결하고 싶으면 People 객체를 하나 만들어서

package com.cos.blog.test;

public class People {
	int hugryState = 50; //100
	
	public static void main(String[] args) {
		People p = new People();
		p.hugryState = 100;
	}
}

배고픔이 이제 100으로 되어서 배고픔이 없어지는건데 이거는 변수에 다이렉트로 접근해서 변수의 값을

변경하는 것인데 이것은 객체지향과 맞지 않는다. 이것은 마법이다.

어떻게 사람이 배고픈데 변수에 바로 접근해서 값을 바로 수정할 수 있겟나요?

배고프다면 이렇게 마법을 부리는 것이 아니라 eat이라는 메서드가 필요하다!

eat이라는 메서드는 hugryState += 10; 로 먹을때마다 10씩 증가를 하기 위해서는 

내가 이제 eat을 실행하고나서 이 상태값을 변경하는것이 이게 맞다.

이게 변수에 다이렉트 로 접근해서 바꾸는 것은 마법일 뿐이다.

 

그러면 그래서 hugryState를 private로 해야한다 왜냐하면 이 변수에 다이렉트로 접근하면 안되기 떄문에! 

그리고 메서드에 Public으로 하여 

이곳에 바로 접근하는것이 아니라

이 함수를 통해서 p.eat(); 을 통해 할 수 가있는데!

해당 클래스가 아닌 다른곳에서 접근하려고 하면 

이렇게 만들어서 홍길동이 hugrystate에 바로 접근하지 못하도록 헀다.

홍길동이 배가 고프면 무엇을 먹어야한다. 

package com.cos.blog.test;

public class TestApp {

	public static void main(String[] args) {
		People 홍길동 = new People();
		홍길동.eat();
	}
}

그래서  객체지향에서는 변수르 private로 만든다. 변수의 상태는 메서드에 의해서 변하도록 설계 해야한다.

우리가 모델을 만들때는 어떤 클래스를 만들때는 변수를 private으로 만들어야한다.

private변수를 수정할 수 있게 상태 값을 변경 할 수 있도록 무엇을 만들어야하는가? 게터와 세터이다. 

package com.cos.blog.test;

public class Member {
	private int id;
	private String username;
	private String password;
	private String email;
	
	public int getId() {
		
		return id;
	}
	public void setId(int id) {
		this.id = id;
	}
	public String getUsername() {
		return username;
	}
	public void setUsername(String username) {
		this.username = username;
	}
	public String getPassword() {
		return password;
	}
	public void setPassword(String password) {
		this.password = password;
	}
	public String getEmail() {
		return email;
	}
	public void setEmail(String email) {
		this.email = email;
	}
	
	
}

이 함수를 통해서 접근해서 수정 한다는것이다. 

그리고 생성자를 만들려고한다! 

그리고 HttpControllerTest에서 무엇을 할것인가? 

Get 요청시에  데이터를 실어 보낼것인데 무엇을 받을것인가? 

http://localhost:8080/http/get 이것을 통해 요청할것인데 ?(물음표)를 하나 붙이고 id=1 하고 포스트맨에서 Send를 하면

http://localhost:8080/http/get?id=1 

get요청응답은 되는데 내가 전송한 데이터 물음표 뒤에있는 id=1은 쿼리 스트링이라고 하는데

쿼리 스트링 id=1을 보내게되면 받을 수 있게 된다.

 

	//http://localhost:8080/http/get (select)
	@GetMapping("/http/get")
	public String getTest(@RequestParam int id) {
		return "get 요청";
	}

보내는 값이 1이니까 ind id가 되면 이제 받을 수있게된다.

//인터넷 브라우저 요청은 무조건 get요청밖에 할 수 없다.
	//http://localhost:8080/http/get (select)
	@GetMapping("/http/get")
	public String getTest(@RequestParam int id, @RequestParam String username) {
		return "get 요청 : "+id+"," + username;
	}

이러한 값이 나오는데! 한개 한개씩이 아니라 한꺼번에 받을 수 있는 방법이 있다! 

그것은? 


//http://localhost:8080/http/get (select)
@GetMapping("/http/get")
public String getTest(Member m) {
return "get 요청 : "+m.getId()+"," + m.getUsername();
}

이렇게 해도 값은 똑같이 나온다! 

여기서 하나더 추가를 하자면? 

 

//http://localhost:8080/http/get (select)
@GetMapping("/http/get")
public String getTest(Member m) {
return "get 요청 : "+m.getId()+"," + m.getUsername() +"," +m.getPassword();
}

실행을 하면 RequestParam을 하면 하나하나 받아줘야하는데 Member 오브젝트를 바로 적어주면 알아서 값들이

매핑이 되어서 들어온다.  패스워드는 이메일을 안보냈기 때문에

이렇게 null이라고 뜨는데 왜냐하면 보내지 않았으니까

null이 ssar@nate.com이 되기 위해서는 

http://localhost:8080/http/get?id=1&username=ssar&password=1234&email=ssar@nate.com

이렇게 작성하면 

만약 http://localhost:8080/http/get?id=1&username=ssar&password=1234&email=ssar@nate.com

여기에서 email을 ema라고 했으면 오류가 될것이다. 왜냐하면 Member 오브젝트는 ema라는걸 들고 있지 않고 있기 떄문이다.

한마리도 Get방식으로하여 쿼리 스트링을 데이터를 실어 보내면 ?(물음표) 뒤에 있는 이 값은 컨트롤러에서

어떻게 하냐면 물음표 ? 뒤에 있는 이 값을 Member 오브젝트에 집어 넣어주는 역할을 스프링이 해준다!

굉장히 좋다! 

Get방식으로 데이터를 요청할떄 어떤 데이터를 요청할것인지 요청하는 방법은 쿼리 스트링 방법밖에 없다.

 

이번에는 Post방식으로 요청을 할것인데 회원가입을 해보자 

POST는 데이터 한건을 추가해 라는 뜻이 있는데 어떤 데이터를 추가 할것인가?

내 회원정보를 추가해서 회원가입을 할것이다! 애가 데이터를 받아야한다 

@RequestParam으로 해도 되지만 아까와 같이 Member M으로 해보자 

 

//http://localhost:8080/http/post (insert) 
@PostMapping("/http/post")
public String postTest(Member m) {
return "post요청 : "+m.getId()+"," + m.getUsername() +"," +m.getPassword() +"," +m.getEmail();
}

근데 여기서 포스트맨으로 요청할때 post는 ?를 붙이고 쿼리 스트링으로 보내는것이 아니라 

포스트 요청은 데이터를 주소에 붙여 보내는것이 아니라 Body라는 곳에 담아 보낸다

그떄 방법이 굉장히 다양하다 근데 대표적으로 2개만 사용해보자 

이 방법을 사용해보려고하는데 머랑 똑같은가? Html에서 <form>태그를 통해 데이터를 요청해본적이 있을것이다.

이런 방식으로 요청하는 방식이 x-www-form-urlencoded 방식이다.

요청이 되었다! 그대로 결과가 나오는데 이것이 가장 기본적인 Post 요청 방식이다.

실제로 Html으로 form태그를 만드는것과 포스트맨에서 하는것과 똑같다.

 

이제 다른 방법으로 요청하려고 한다. JSON 데이터로 요청을 해보기전에! 

간단하게 텍스트로 요청을 해보려고 하는데 

이렇게 하면 애가 응답을 받지 못한다 400 이라는 오류가 난다.

Bad Reqeust라는것은 요청이 잘못되었다는 것이다.

이번에는 //http://localhost:8080/http/post (insert) 
@PostMapping("/http/post")
public String postTest(String text) {
return "post요청 : " +text;

이렇게 저장해서 

Post 요청이 null이 뜬다. 그러면? 이렇게는 받지 못한다는건데 

아까전에 Get방식으로 요청을 할떄는 RequestParam이라는걸 했는데

Body 데이터는 RequestBody라고 어노테이션을 줘야한다 

무엇을 쓰든 그대로 받을것이다. 누가 받게 되는것인가? 

text라는 변수가 받는다! 어떤 데이터를 ? Body 데이터를 받게된다!

 

그러면 이번에는 raw을 할것인데 우린 방금 text를 보냈는데 raw는 가장 낮은 Raw 데이터라는건 가장 기본적인 데이터라는 것이다. text/plain 평문을 보냈다는 것이다.

 

이번에는 application/json 데이터를 보내보려고 한다! 

이것이 Json 데이터 타입이다. 그래서 왼쪽에 있는것이 Key이다. Key는 항상 String 값이기 때문에

항상 쌍 따옴표가 있어야한다. 오른쪽에 있는 것들은 숫자, 문자 , Json오브젝트 등 다양한것을 넣을 수 있는데

우리는 저렇게 요청을 하게 되는데?!

이렇게 날라오게된다. 내가 직접 보낸것이 일반적인 텍스트라는것이다.

생긴것은 Json처럼 생겼는데 내가 보낸것은 application/json이 아니라 text/plain으로 보낸것이다.

text애는 머가 담기는가? {
   "id" : 1,
   "username" : "ssar",
   "password" : 123456,
   "email" : "ssar@nate.com"
}

이것이 그대로 담기는 것이다! 

JSON으로 바꾸면 밑에 글씨 색상도 바뀐다. 

똑같이 결과가 보일것이다. 이런 정보들을 java에서 처리하기 위해서는 text안에 담겨 있는 이 데이터를 처리하기가 굉장히 힘들다. 그래서 Membe

	//http://localhost:8080/http/post (insert) 
	@PostMapping("/http/post") //text/plain
	public String postTest(@RequestBody Member m) {
		return "post 요청 : "+m.getId()+"," + m.getUsername() +"," +m.getPassword() +"," +m.getEmail();
	}

이렇게 나올것이다.

포스트 요청을 할건데 어떤 데이터를 실었는가 JSON데이터를 실었다.

애가 MIME 타입은 application/json 이 될것이고! text로 바꾸면 text/plain이 날라가는것이고 

 

그러면 applicaiton/json이 날라가니까 스프링 부트는 재들을 Member m이라고 적어 놓으면 이 오브젝트에 그대로

매핑을 해서 넣어준다.

만약에 우리가 Member m이라 적었는데 데이터를 보낼때 text를 보내게 되면 제대로 응답하지 못한다.

왜냐하면 내가 보낸데이터가 text인데 text로 날라왔으니까 일반 문자열이니까 여기에 딱 매핑이 안된다.

application/json이라고 적어서 send를 하면 애가 저절로 파싱을 해서 오브젝트에 넣어준다.

 

이 일을 누가하는가? MessageConverter(스프링부트) 라는 애가 한다.

아까 get 도 마찬가지다. 여기에서 오브젝트에 쿼리 스트링 값을 매핑해주는것이 스프링부트의 MessageConverter라는 클래스가 자동으로 매핑을 해준다! 

굉장히 편안하다

우리가 수정하고 싶을때도 데이터를 보낼떼 

body에다가 내가 수정하고 싶은 데이터가 있으면 이번에는 

지금은 받고있는것이 없기 떄문에  모르겠지만 받게 만들어보자!

이 두값을 받으려면 방법은 JSOn데이터가 날라왔으니까 Body데이터니까 @RequestBody Member m

 

당연히 이메일이랑 유저네임은 날리지 않았으니까 못받는것이다.

Delete도 마찬가지이다. 바디에 데이터를 실어서 보내면

스프링에서는 굉장히 간단하게 오브젝트에 매핑해서 받을 수 있는데 

@Requestbody라는 어노테이션을 통해서 오브젝트에 매핑해서 받을 수 있다!