Spring 부트

23-02-16) 스프링부트 7강 - REST API

JadeStone 2023. 2. 16. 17:49

* REST API 를 이용하면 서버간에 통신을 할 수 있다. (핵심)

* 네트워크는 객체를 모름. 따라서 객체를 문자열로 바꿔서 주거니 받거니 하게 됨.

  이 문자열 형태 중 대표적으로  xml , JSON  이 2가지 방식을 사용.

  즉, 자바의 객체를 보내거나 받을 때 xml이나 Json 형식으로 바꿔서 보내고 받는다.

 

* 서버간 데이터 통신방식은 양방향 방식

* 기본적으로 클라이언트 (페이지)에서 넘어온 값을 컨트롤러에서 받는 기본적인 방법은

HttpServletRequest 인데 다른방법으로도 넘어오는 데이터를 받을 수 있는 이유는

Argument Resolver에서 내부적으로 처리를 해주기 때문.

 

# REST API의 특별한 어노테이션

* @RequestBody 

- Json  으로 넘어오는 값을 자바 객체로 바꿔주는(맵핑) 어노테이션.

* @ReponseBody

- 들어온 요청을 요청을 보낸 곳으로 다시 돌려보내줄 때 사용.

( 요청을 보낸 상대방에게 자바내용을 제이슨 형식으로 바꿔서 다시 보내줄 때 사용 )

 

★ 스프링 부트는

    용도 자체가 REST 컨트롤러 전용이라 view 가 원래 없는 것.

 

@RestController 

-  Controller + responseBody 의 합성어. 

   return 에 실어주는 내용을 제이슨 형식으로 바꾸어서 상대방 서버로 보내줌.

 

 

#Jackson-databind

 * 스프링에서는 이 모듈을 다운받아줘야하지만

   스프링 부트에서는 이미 내장되어 있음 (json 형식만 바인딩 가능).

xml 까지 바인딩 해주고자 한다면 따로 모듈 더 추가해줘야 함.

  

# @PathVariable 

get방식 데이터를 추출한다.

 

# RestController의 전송방식  ( 간단히 보고 넘어감)

 

# 컨슈머, 프로듀서

* 컨슈머: 들어오는 데이터 타입을 제한

* 프로듀서: 보내주는 데이터의 타입은 이거라고 명시해주는 것.

이 내용을 생략하면 저절로 컨슈머,프로듀서 둘 다에 application/json 형식으로 들어감.

 

 

구글확장프로그램(부메랑) 설치.

부메랑 홈페이지 들어가보기.

 

#마임타입

MIME 타입이란 클라이언트에게 전송된 문서의 다양성을 알려주기 위한 메커니즘입니다: 웹에서 파일의 확장자는 별 의미가 없습니다. 그러므로, 각 문서와 함께 올바른 MIME 타입을 전송하도록, 서버가 정확히 설정하는 것이 중요합니다.

* 어떤 데이터 타입으로 명시해서 보내준다고 해야할지 헷갈릴 때 참고 싸이트 링크 : 

https://developer.mozilla.org/ko/docs/Web/HTTP/Basics_of_HTTP/MIME_types

 

<RestController 에서 다른서버로 값 보내고 받아보기>

 

# 반환

@RestController // Controller + ResponseBody
public class RestBasicController {
	
	/*
	 * 1. Responsebody는 return값이 뷰리졸버가 아니고, 요청이 들어온곳으로 반환됩니다.
	 */
	
	@GetMapping("/getText")
	public String getText() {
		return "hello world";
	}
	
	//객체를 담게 되면 application/json 형식으로 반환하게 됩니다.
	/*
	 * produces - 보내는 데이터에 대한 타입
	 */
	@GetMapping(value = "/getObject", produces = "application/json")
	public SimpleVO2 getObject() {
		SimpleVO2 vo = new SimpleVO2("aaa123", "홍길동", "1");
		return vo;
	}
	
	//맵형식의  반환
	@GetMapping("/getObject2")
	public Map<String, Object> getObject2(){
		Map<String, Object> map = new HashMap<>();
		SimpleVO2 vo = new SimpleVO2("aaa123", "홍길동", "1");
		map.put("totla", 100);
		map.put("data", vo);
		
		return map;
	}
	
	//리스트 형식의 반환
	@GetMapping("/getObject3")
	public List<SimpleVO2> getObject3(){
		List<SimpleVO2> list = new ArrayList<>();
		for(int i = 1; i <= 10; i++) {
			list.add(new SimpleVO2("aaa123" + i, "홍길동" + i, "1"));
		}
		
		return list;
		
	}

 

# get 형식으로 값을 받는 방법 

	//get형식 값을 받는방법 1 - 쿼리스트링 ?키=값
	//http://localhost:8383/getKey?id=aaaa&name=홍길동
	@GetMapping("/getKey")
	public String getKey(@RequestParam("id") String id,
						 @RequestParam("name") String name) {
		System.out.println(id);
		System.out.println(name);
		
		return "success";
		
	}
	
	//get형식 값을 받는방법2 - 쿼리파람 URL/키/키
	@GetMapping("/getPath/{sort}/{apiKey}")
	public String getPath(@PathVariable("sort") String sort,
						  @PathVariable("apiKey") String key) {
		System.out.println(sort);
		System.out.println(key);
		
		return "success";
	}

 

# post 방식으로 값을 받기

post 방식은 기본적으로 제약사항이 따라옴.

 

*form 형식으로 데이터 받기

- 클라이언트에서 데이터를 폼형식으로 보내면 바로 받아짐. 

 하지만 json 형식은 아님( json 을 자바의 객체로 바꿔주는 작업이 필요).

 

	///////////////// post 형식의 처리 ///////////////////
	
	//값을 받는방법 1 - VO로 맵핑
	//JSON형식의 데이터를 자바의 객체로 맵핑 -> @RequestBody
	//{"id": "aaa", "name":"bbb"}
	@PostMapping("/getJson")
	public String getJson(@RequestBody SimpleVO2 vo) {
		
		System.out.println(vo.toString());
		
		return "success";
	}

 

 

*JSON 방식으로 데이터 받기

- 그냥 이렇게만 보내면 자바 측에서는 제이슨 형식을 모르기 때문에 값이 안 받아짐 

 그래서 @RequestBody 어노테이션을 씀으로써

 제이슨 형식을 자바의 객체로 맵핑해주게 함.

 

	//값을 받는방법 1 - VO로 맵핑
	//JSON형식의 데이터를 자바의 객체로 맵핑 -> @RequestBody
	//{"id": "aaa", "name":"bbb"}
	@PostMapping("/getJson")
	public String getJson(@RequestBody SimpleVO2 vo) {
		
		System.out.println(vo.toString());
		
		return "success";
	}

 

* Map으로 맵핑

부메랑에서 값을 보내옴

서버에서 보내온 값을 받음.

	@PostMapping("/getMap")
	public String getMap(@RequestBody Map<String, Object> map) {
		System.out.println(map.toString());
		return "success";
	}

 

 

# consumer를  통한 데이터 제한  ★★★

 

★ 양방향 통신의 규약

받는 측과 보내는 측에서의 각각 데이터 타입을 맞춰줘야함.

( 보내는 측에서는 보내는 타입이 뭔지, 

  받는 측에서는 어떤 타입으로 받을건지 꼭 명시해야 함.

명시 안하면 기본으로 application/Josn 형식으로 지정됨.

)

 

클라이언트에서 

1 보내는 타입 명시  Content-Type

2 받는 타입 명시  Data_Type

 

서버에서

1 받는타입 명시 consumer

2 보내는 타입 명시 producer 

 

1과 2는 각각 짝이된다.

 

 

 

# 응답문서의 형태를 직접선언 - ResponseEntity

 

*ResponseEntity 란?

 

Spring Framework에서 제공하는 클래스 중 HttpEntity라는 클래스가 존재한다. 이것은 HTTP 요청(Request) 또는 응답(Response)에 해당하는 HttpHeader HttpBody를 포함하는 클래스이다. 

 

HttpEntity 클래스를 상속받아 구현한 클래스가 RequestEntity, ResponseEntity 클래스이다. ResponseEntity는 사용자의 HttpRequest에 대한 응답 데이터를 포함하는 클래스이다. 따라서 HttpStatus, HttpHeaders, HttpBody를 포함한다. 

 

* 왜 사용하는가 ? 

 

body 에는 데이터 값,

header 에는 요청/응답 에 대한 요구사항이,

status에는 응답,요청이 성공했는지 여부를 알려주느 상태코드가 담긴다.

반환은 위에 내용들을 매개변수에 담아준 ResponseEntity 객체를 반환해주면됨.

★ ResponseEntity의 제너릭 타입은 데이터 타입을 따라감을 주의하자.

	//응답문서의 형태를 직접선언 - ResponseEntity
	@PostMapping("/createRes")
	public ResponseEntity createRes() {
		
		SimpleVO2 vo = new SimpleVO2("aaa", "홍길동", "1"); //데이터
		
		HttpHeaders header = new HttpHeaders();
		header.add("Authrization", "token");
		
		HttpStatus status = HttpStatus.ACCEPTED; //상태코드 (성공 or 실패)
		
		//제네릭은 데이터를 따라갑니다.
		ResponseEntity<SimpleVO2> entity = new ResponseEntity<>(vo, header, status);
		
		return entity;
	}

 

 

 

https://inpa.tistory.com/entry/WEB-%F0%9F%93%9A-CORS-%F0%9F%92%AF-%EC%A0%95%EB%A6%AC- %ED%95%B4%EA%B2%B0-%EB%B0%A9%EB%B2%95-%F0%9F%91%8F

 

*서버 와 서버의 도메인주소가 서로 다르면

자동으로 서버는 블락을 시킴.

* Cross origin resources sharing 

 

*리액트에서 자바스프링부트 서버로 요청

import axios from "axios";

const App = () => {

    const handleClick = async () => {
        const data = {"id": "aaa", "name":"bbb"}
        const result = await axios.post("http://localhost:8383/getJson",data)

        console.log(result);
    }

    return(
        <div>
            <input type="button" onClick={handleClick} value="데이터요청하기"/>
        </div>
    )

}

export default App;

리액트 창에서 데이터 요청하기 버튼을 누름.

자바 서버(스프링부트)로 이동.

 

 

* 자바 서버(스프링부트) 에서 크로스 오리진을 해제하여 리액트의 요청을 받게끔 처리함.

- 도메인이 다른 서버에서 요청이 올 때 

  크로스 오리진을 해제해주고자 한다면 무조건 서버측에서 해줘야함.

  아래와 같이 

 @CrossOrigin ("요청주소")  어노테이션을 요청을 처리해주는 메서드 위에 적어주면 됨.

	//cors - 기본적으로 서버가 다르면 요청을 거절하는데 (특정 서버에 대하여 허용)
	//@@CrossOrigin(*)
	@CrossOrigin("http://localhost:3000")
	@PostMapping("/getJson")
	public String getJson(@RequestBody SimpleVO2 vo) {
		
		System.out.println(vo.toString());
		
		return "success";
	}

리액트에서 보내온 데이터를 잘 받았는지 자바 서버에서 확인

 

리액트 창에서 데이터 요청을 반환받은 결과