api를 다른 서버에서 요청하기 위해
1. pom.xml - 서버끼리 통신할 수 있게 해주는 webflux 라이브러리 넣어주기
<!-- 서버와 서버를 통신할 수 있게 해주는 -->
<!-- web client(webflux) -->
<!-- https://mvnrepository.com/artifact/org.springframework.boot/spring-boot-starter-webflux -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-webflux</artifactId>
</dependency>
2. index.html
클릭하면 getSend() 함수가 실행된다
이 함수는 ajax함수이고 요청주소가 '/get/send/'+$('#msg').val()이다
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
<script src="https://code.jquery.com/jquery-3.6.3.min.js"></script>
</head>
<body>
<h3>INDEX PAGE</h3>
<input type="text" id="msg"/>
<button onclick="getSend()">GET SEND</button>
<br/><br/>
<input type="number" id="cnt"/>
<button onclick="postSend()">POST SEND</button>
<P><button onclick="fluxTest()">FLUX TEST</button></P>
</body>
<script>
function getSend() {
$.ajax({
url:'/get/send/'+$('#msg').val(),
type:'get',
data: {},
dataType: 'json',
success:function(data){
console.log(data);
},
error:function(e){
console.log(e);
}
});
}
//숫자 전송 -> 숫자만큼 리스트를 가져온다
//헤더에 값을 넣어서 보낸다
function postSend() {
$.ajax({
url:'/post/send/'+$('#cnt').val(),
type:'post',
data: {},
dataType: 'json',
beforeSend:function(header){//전송하기 전에 체크 작업같은거 할때 beforesend 이용함
console.log(header);
header.setRequestHeader("Authorization","a12345")
},
success:function(data){
console.log(data);
},
error:function(e){
console.log(e);
}
});
}
function fluxTest() {
$.ajax({
url:'/get/fluxTest',
type:'get',
data: {},
dataType: 'json',
success:function(data){
console.log(data);
},
error:function(e){
console.log(e);
}
});
}
</script>
</html>
2. SendController
package kr.co.gudi.controller;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestHeader;
import org.springframework.web.bind.annotation.RestController;
import kr.co.gudi.service.SendService;
@RestController
public class SendController {
Logger logger = LoggerFactory.getLogger(getClass());
//생성자 주입
private final SendService service;
public SendController(SendService service) { //생성자에 넣어줌
this.service = service;
}
@GetMapping(value="/get/send/{msg}")
public HashMap<String, String> send(@PathVariable String msg){
logger.info("가져온 msg : "+ msg);
return service.getSend(msg);
}
@PostMapping(value="/post/send/{cnt}")
public ArrayList<HashMap<String, Object>> postSend(@PathVariable String cnt, @RequestHeader HashMap<String, String> header){
logger.info("header : {}",header);
header.get("authorization");
return service.postSend(cnt, header.get("authorization"));
}
@GetMapping(value="/get/fluxTest")
public List<HashMap<String, Object>> fluxTest(){
return service.fluxTest();
}
}
3. SendService
package kr.co.gudi.service;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.stream.Collectors;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;
import org.springframework.web.reactive.function.BodyInserters;
import org.springframework.web.reactive.function.BodyInserters.FormInserter;
import org.springframework.web.reactive.function.client.WebClient;
import reactor.core.publisher.Mono;
@Service
public class SendService {
Logger logger = LoggerFactory.getLogger(getClass());
/*webclient는 spring 5.0부터 지원한다
*전에는 외부서버와 통신할 때 HttpConnection을 사용했었음 -> RestTemplate로 바뀜 -> 지금은 WebClient(=webflux : 비동기라 속도면에서 우월, 순서없이 날라가는게 문제)
* webClient는 non-blocking(비동기) 방식을 지원하며, 속도가 빠르다
* */
public HashMap<String, String> getSend(String msg) {
//1. 전송 URL 설정
WebClient client = WebClient.create("http://localhost");
//2. 전송 방식을 선택 (get)
//3. 추구할 URL이 있다면 설정(없어도 됨)
//client로 요청을 보낼때 get방식으로 보낼거고 uri를 추가요청할거고, retrieve는 응답의 body값을 가져올거고
그렇게 가져온 body는 bodytoMono를 통해 mono로 바꾸는데 데이터타입은 hashMap인거임
Mono<HashMap> mono = client.get().uri("/return/"+msg)
.retrieve() //4. 전송(어떻게 보낼 것인지? 무엇을 받을 것이지?)
.bodyToMono(HashMap.class); //5. 받아올 방식을 설정(형태, 처리방식)
HashMap<String, String> resp = mono.block(); //그렇게 담아온 mono를 blcck을 통해 하나씩 빼냄
logger.info("resp :{}",resp);
return resp;
}
public ArrayList<HashMap<String, Object>> postSend(String cnt, String key) {
WebClient client = WebClient.create("http://localhost"); //이 url로 요청을 보내겠다는겁니다
//post방식으로 보내자
//get에서는 url에 파라메터를 보냈지만, post에서는 바디에 보내야 한다, 그래서 아래처럼 파라메터를 넣는다
FormInserter<String> form = BodyInserters.fromFormData("cnt",cnt);
//BodyInserters: 비동기 방식에서 body를 구성하기 위해서 사용
//fromFormData: cnt 값을 body에 넣기 위해 사용
//form.with("name",'kim');//cnt같은걸 여러개 넣고싶을 경우 form.with 사용
Mono<ArrayList> mono = client.post().uri("/listReturn")
.header("authorization", key).body(form) //post방식으로 보낼 땐 header와 body가 필요하다
.retrieve().bodyToMono(ArrayList.class);
//block은 사용이 편리하지만 권고하지 않음(동기방식이라 비효율적, 요청량이 많으면 병목현상 일어나서 다른 방식 써야함)
//ArrayList<HashMap<String, Object>> resp = mono.block();
//어떻게 할거냐면 비동기로 받아놓고(flux) 줄을 세워서 하나씩(toStream,약간 forEach같은거, 1개짜리 배열이라고 생각) 맨 앞사람부터(findFirst) 가져와(get)
ArrayList<HashMap<String, Object>> resp = mono.flux().toStream().findFirst().get();
logger.info("resp : {}",resp);
return resp;
}
public List<HashMap<String, Object>> fluxTest() {
WebClient client = WebClient.create("http://localhost"); //기본 url
//json형태로 파라메터 보내기(json형태로 보내려면 hashmap 써야함)
HashMap<String, Object> params = new HashMap<String, Object>();
params.put("age", 22);
params.put("name", "Lee");
params.put("married", false);
params.put("scores", new int[] {80,90,100,80,70});
//client를 post방식으로 보내는데 fluxReturn이라는 추가값/ json형태로 보낼 때는 bodyValue를 사용하면된다
//받을 때는 @RequestBody로 받아야 한다
//retrieve로 나옴 flux로 값을 받음 Stream으로 줄세우고 근데 arraytlist로도 받는다? collect를 통해 list 형태로 한꺼번에 가져온다
List<HashMap<String, Object>> list = client.post().uri("fluxReturn").bodyValue(params).retrieve()
.bodyToFlux(HashMap.class).toStream().collect(Collectors.toList());
return list;
}
}
4. ReceiveController
ArrayList<HashMap<String, Object>>
이런 데이터 타입 스는 이유는
여러 가지 값을 보낼건데 그안에있는 값들이 hashmap타입으로 key,value로 이루어져있기때문
package kr.co.gudi.controller;
import java.util.ArrayList;
import java.util.HashMap;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.web.bind.annotation.CrossOrigin;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestHeader;
import org.springframework.web.bind.annotation.RestController;
@RestController //여기에 response body 있는 덕분에 보내준 곳으로 다시 답 보냄
@CrossOrigin(value="*")
public class ReceiveController {
Logger logger = LoggerFactory.getLogger(getClass());
@GetMapping(value="/return/{msg}")
public HashMap<String, String> getReturn(@PathVariable String msg){
logger.info("받은 메시지 : " + msg);
HashMap<String, String> result = new HashMap<String, String>();
result.put("your_msg", msg);
return result;
}
//cnt로 그만큼 list를 만들어줌, list에 그 key값을 가진 회원 있어?
@PostMapping(value="/listReturn")
public ArrayList<HashMap<String, Object>> postReturn(int cnt,
@RequestHeader HashMap<String, String>header){
logger.info("receive : "+cnt);
logger.info("receive key : "+header.get("authorization"));
ArrayList<HashMap<String, Object>> list = new ArrayList<HashMap<String,Object>>();
HashMap<String, Object> map = null;
for(int i = 1; i<=cnt; i++) {
map = new HashMap<String, Object>();
map.put("no", i);
map.put("name", "kim");
map.put("salary", i*100000000);
list.add(map);
}
return list;
}
@PostMapping(value="/fluxReturn")
public ArrayList<HashMap<String, Object>> fluxReturn(
@RequestBody HashMap<String, Object>params){
logger.info("가져온 params : "+params);
ArrayList<HashMap<String, Object>> list = new ArrayList<HashMap<String,Object>>();
HashMap<String, Object> map = null;
for(int i = 1; i<=10; i++) {
map = new HashMap<String, Object>();
map.put("no", i);
map.put("name", "kim");
map.put("salary", i*100000000);
list.add(map);
}
return list;
}
}
자세히 써놨으니 다 읽어볼것
'Spring Boot' 카테고리의 다른 글
crawling 크롤링 (0) | 2023.06.08 |
---|---|
dd (0) | 2023.06.05 |
WebClient (0) | 2023.05.31 |
필드 주입과 생성자 주입, rest, @RestController (0) | 2023.05.30 |
spring boot 스프링부트 (0) | 2023.05.25 |