외부 api = 지도, 소셜로그인, 공공DB, 결제, 페이//…
외부 API의 형태
- json = xml보다 용량이 작고 구조가 단순
- xml = json보다 용량이 크다
xml 형태를 받아와서 json 형태로 변환하면 된다
변환된 JSON형태를 꺼내어 사용하면 된다
데이터를 DB에 저장할때 제일좋은 방법은
해당 데이터의 entity를 만들어 넣는것이다
➡️ 조금 번거로울 수는 있다
RestController에서 Spring boot에서 제공하는 RestTemplate을 사용하여 API 가져오기
json문서 파싱을 위한 라이브러리 설치
<!-- json문서 파싱을 위한 라이브러리 -->
<dependency>
<groupId>org.json</groupId>
<artifactId>json</artifactId>
<version>20211205</version>
</dependency>
API 예시 http://1.234.5.158:13000/json/exam1.json
🛠 로직
1. api호출하여 결과를 가져오기
➡️ 대부분의 API는 get형태가 많다 = 정보를 가져오거나 받아오는 형태
2. 가져온 데이터를 반환해준다
3. DB에 저장해준다
Spring boot에서 제공하는 RestTemplate을 사용하여 API를 가져온다
RestTemplate.getForObject(URI url, Class<T> responseType) => (호출하는 url, 반환타입)
데이터를 컨트롤러에 넣을 수 있어야 DB에 저장이 가능하다
// JSON형태의 api받아오기
// 127.0.0.1:8080/BOOT1/api/exam1.json
@GetMapping(value = "/exam1.json")
public Map<String, Object> exam1GET() {
Map<String, Object> map = new HashMap<>();
try {
// 소셜 로그인 , 공공api 등의 url
String url = "http://1.234.5.158:13000/json/exam1.json";
// Spring boot에서 제공하는 RestTemplate
RestTemplate restTemplate = new RestTemplate();
// 1. api호출하여 결과를 가져오기
// RestTemplate.getForObject(URI url, Class<T> responseType) => (호출하는 url, 반환타입)
String response = restTemplate.getForObject(url, String.class);
// 2. 가공된 데이터를 반환
System.out.println(response);
// 3. DB에 저장
// {"ret" : "y", "data":"123"}
JSONObject jobj = new JSONObject(response.toString());
String ret1 = jobj.getString("ret"); // y
String ret2 = jobj.getString("data"); // 123
System.out.println(ret1 + "," + ret2);
} catch (Exception e) {
e.printStackTrace();
}
return map;
}
결과화면
API 예시 http://1.234.5.158:13000/xml/exam1.xml
🛠 로직
1. api호출하여 결과를 가져오기
➡️ 대부분의 API는 get형태가 많다 = 정보를 가져오거나 받아오는 형태
2. 가져온 데이터를 가공하여 반환해준다
3. DB에 저장해준다
// XML형태의 api받아오기
// 127.0.0.1:8080/BOOT1/api/exam100.json
@GetMapping(value = "/exam100.json")
public Map<String, Object> exam100GET() {
Map<String, Object> map = new HashMap<>();
try {
// 소셜 로그인 , 공공api 등의 url
String url = "http://1.234.5.158:13000/xml/exam1.xml";
// Spring boot에서 제공하는 RestTemplate
RestTemplate restTemplate = new RestTemplate();
// 1. api호출하여 결과를 가져오기
// 대부분의 api는 get형태가 많다 = 정보를 가져오거나 받아오는 형태
// RestTemplate.getForObject(URI url, Class<T> responseType) => (호출하는 url, 반환타입)
String response = restTemplate.getForObject(url, String.class);
// XML을 JSON Object로 변환하기
JSONObject jobj = XML.toJSONObject(response);
// 변환된 데이터 확인
// {"response":{"items":{"item":[{"name":"one","id":1},{"name":"two","id":2},{"name":"three","id":3}]}}}
System.out.println("--------------jobj.toString---------------");
System.out.println(jobj.toString());
// 3. 데이터에서 꺼내어쓰기
JSONObject jobj1 = jobj.getJSONObject("response").getJSONObject("items");
// {"item":[{"name":"one","id":1},{"name":"two","id":2},{"name":"three","id":3}]}
System.out.println("--------------jobj1---------------");
System.out.println(jobj1.toString());
// 배열 형태이니 반복문을 이용
// [
// {"name":"one","id":1},
// {"name":"two","id":2},
// {"name":"three","id":3}
// ]
JSONArray jarr = jobj1.getJSONArray("item");
System.out.println(jarr.length());
for (int i = 1; i < jarr.length(); i++) {
// {"name":"one","id":1}
String name = jarr.getJSONObject(i).getString("name");
int id = jarr.getJSONObject(i).getInt("id");
}
System.out.println("--------------jarr---------------");
System.out.println(jarr);
// map.put("jobj", jobj.toString());
// String ret1 = jobj.getString("items"); //y
// String ret2 = jobj.getString("data"); //123
// System.out.println(ret1 + "," + ret2);
} catch (Exception e) {
e.printStackTrace();
}
return map;
}
API 예시 http://1.234.5.158:13000/json/exam2.json
배열형태의 JSON API 받아오기
배열형태의 데이터는 DTO생성하고 넣는게 좋다
row 는 [ ]
형태 변수 하나를 갖는다
row를 Exam2DTO
로 꺼내고
row안의 Exam1DTO
형태의 2개의 object를 꺼냄
받아온 API의 형태가 JSON형태라면 바로 DTO에 넣으면 되는데
xml형태인 경우
⇒ String 으로 먼저 받고 수동으로 json형태로 변환해주거나
⇒ String 으로 먼저 받고 json형태로 변환 후 map에 넣어 DTO에 담아줄 수 있다
xml을 DTO에 넣는경우에는 DTO로 바로 받을 수 없으며
map으로 변환하는 수동작업이 필요하다
2. 배열형태의 XML API를 Map에 담기
방법으로 수동으로 map으로 넣어주면 된다
⇒ 코드 양이 길어지는 단점이 있다
이때 받아온 데이터를 전부 DTO로 바꾸는게 아니라
map에 필요한 데이터만 저장하여 DTO에 넣어 사용하거나 화면에 출력한다
꼭 restcontroller 에서만 API를 받아오는게 아니라 controller에서 API를 받아와서 view에 출력이 가능하다
🛠 로직
1. api호출하여 결과를 가져오기
➡️ 대부분의 API는 get형태가 많다 = 정보를 가져오거나 받아오는 형태
2. Exam2DTO의 형태로 먼저 꺼내온다
3.response.getRow()
만큼 반복문을 실행하여
3. map에 담아 반환해준다
여러개의
Exam1DTO
=List<Exam1DTO> row
를 가지는Exam2DTO
를 생성해준다
package com.example.dto;
import java.util.List;
import lombok.Data;
@Data
public class Exam2DTO {
List<Exam1DTO> row;
}
row
안 배열 형태를 확인하여 DTO를 생성해준다
package com.example.dto;
import lombok.Data;
@Data
public class Exam1DTO {
String ret;
String data;
}
// 127.0.0.1:8080/BOOT1/api/exam2.json
// 이 방법이 제일 간편!
@GetMapping(value = "/exam2.json")
public Map<String, Object> exam2GET() {
Map<String, Object> map = new HashMap<>();
try {
// 소셜 로그인 , 공공api 등의 url
String url = "http://1.234.5.158:13000/json/exam2.json";
// Spring boot에서 제공하는 RestTemplate
RestTemplate restTemplate = new RestTemplate();
// 1. api호출하여 결과를 가져온 다음
// 대부분의 api는 get형태가 많다 = 정보를 가져오거나 받아오는 형태
// RestTemplate.getForObject(URI url, Class<T> responseType) => (호출하는 url, 반환타입)
// Exam2DTO의 형태로 먼저 꺼내온다
Exam2DTO response = restTemplate.getForObject(url, Exam2DTO.class);
// Exam2DTO의 getRow()를 꺼낸다 => List<Exam1DTO> 타입
for (Exam1DTO obj : response.getRow()) {
// Exam1DTO(ret=y1, data=123)
// Exam1DTO(ret=y2, data=234)
System.out.println("============");
System.out.println(obj.toString());
}
} catch (Exception e) {
e.printStackTrace();
}
return map;
}
출력결과
API 예시 http://1.234.5.158:13000/json/exam2.json
🛠 로직
1. api호출하여 결과를 가져오기
➡️ 대부분의 API는 get형태가 많다 = 정보를 가져오거나 받아오는 형태
2. XML을 String 형태로 먼저 받아오기
3. JSON객체로 변환해주기
4. 변환된 JOSON객체를 map에 담은 후 DTO와 매칭하여 변환하기
convertValue(json.toMap(), Exam2DTO.class)
➡️ map을 DTO와 매칭
// map을 이용해 DTO에 넣어주기
// 127.0.0.1:8080/BOOT1/api/exam200.json
@GetMapping(value = "/exam200.json")
public Map<String, Object> exam200GET() {
Map<String, Object> map = new HashMap<>();
try {
// 소셜 로그인 , 공공api 등의 url
String url = "http://1.234.5.158:13000/json/exam2.json";
// Spring boot에서 제공하는 RestTemplate
RestTemplate restTemplate = new RestTemplate();
// 1. api호출하여 결과를 가져온 다음
// 대부분의 api는 get형태가 많다 = 정보를 가져오거나 받아오는 형태
// RestTemplate.getForObject(URI url, Class<T> responseType) => (호출하는 url, 반환타입)
// 2. String형태로 먼저 받기
String response = restTemplate.getForObject(url, String.class);
// 3. JSON객체로 변환
JSONObject json = new JSONObject(response);
// map => DTO로 변환
// json.toMap(), Exam2DTO.class => map을 dto와 매칭
// [Exam1DTO(ret=y1, data=123), Exam1DTO(ret=y2, data=234)]
ObjectMapper mapper = new ObjectMapper();
Exam2DTO exam2 = mapper.convertValue(json.toMap(), Exam2DTO.class);
System.out.println(exam2.getRow().toString());
} catch (Exception e) {
e.printStackTrace();
}
return map;
}
출력결과
API 예시 http://1.234.5.158:13000/json/post1.json
값을 전달해 줄 DTO를 생성한다
package com.example.dto;
import lombok.Data;
@Data
public class Exam1DTO {
String ret;
String data;
}
데이터를 post방식으로 전송 ➡️ map형식이 데이터를 많이 전송 할 수 있다
// 127.0.0.1:8080/BOOT1/api/post1.json
// 외부 api사용하여 데이터 전달하는 경우 = post사용해야 한다
@GetMapping(value = "/post1.json")
public Map<String, Object> getMethodName() {
Map<String, Object> map = new HashMap<>();
try {
String url = "http://1.234.5.158:13000/json/post1.json";
// ret, data의 정보를 post방식으로 전송
// map형식이 데이터를 많이 전송 할 수 있다
Map<String, Object> param = new HashMap<>();
param.put("ret", "999");
param.put("data", "000");
// Spring boot에서 제공하는 rest템플릿
RestTemplate restTemplate = new RestTemplate();
// DTO로 받기, 구조가 복잡하면 String으로 받아서 수동으로 파싱하기
Exam1DTO response = restTemplate.postForObject(url, param, Exam1DTO.class);
System.out.println(response);
} catch (Exception e) {
e.printStackTrace();
}
return map;
}
출력결과
DTO 생성하여 가져온 API 보관하기
API 예시 http://1.234.5.158:13000/board101/select.json?text=&page=1
BoardSelectDTO2
는BoardSelectDTO
형태를 List로 가지고 있으며,
변수 status와 total을 가지고 있다
package com.example.dto;
import java.util.List;
import lombok.Data;
@Data
public class BoardSelectDTO2 {
int status;
List<BoardSelectDTO> rows;
Long total;
}
날짜형태를 가져올때
1. 먼저 String 타입으로 지정하여 데이터를 가져온다
2. String으로 가져온 날짜 데이터를 Date 형태로 알맞게 형변환 시켜준다
➡️ String 형태의 날짜 정보를 적절한 pattern에 맞게 적용하여 Date로 변환해준다!
package com.example.dto;
import java.util.Date;
import com.fasterxml.jackson.annotation.JsonFormat;
import lombok.Data;
@Data
public class BoardSelectDTO {
Long _id;
String title;
String writer;
Long hit;
// // 날짜는 일단 String 타입으로 잡고 형변환 시킨다
// String regdate;
// String 으로 되어있는 날짜 정보를 pattern에 맞게 적용하여 Date로 변환
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
Date regdate;
}
데이터를 컨트롤러에 넣을 수 있어야 DB에 저장이 가능하다
// Board1DTO를 만들어서 보관하기
// String url ="http://1.234.5.158:13000/board101/select.json?text=&page=1";
// 127.0.0.1:8080/BOOT1/api/select.json
@GetMapping(value = "/select.json")
public Map<String, Object> selectGET(
){
Map<String, Object> map = new HashMap<>();
try {
String url = "http://1.234.5.158:13000/board101/select.json?text=&page=1";
// Spring boot에서 제공하는 RestTemplate
RestTemplate restTemplate = new RestTemplate();
BoardSelectDTO2 response = restTemplate.getForObject(url, BoardSelectDTO2.class);
// System.out.println(response.toString());
for (BoardSelectDTO obj : response.getRows()) {
obj.setTitle( obj.getTitle() + "변경된 내용추가" );
System.out.println(obj.toString());
}
map.put("status", response.getStatus());
map.put("total", response.getTotal());
map.put("rows", response.getRows());
} catch (Exception e) {
e.printStackTrace();
}
return map;
}
출력결과