소환사 최근 전적 데이터 가져오기
소환사 최근 전적의 경우 서로 다른 두개의 API 를 연계하여 구현해야 했다.
먼저 해당 소환사의 puuid 값을 가지고 가장 최근 매치 부터 지정된 숫자 만큼의 갯수만큼 매치 id 값을 API 를 통해 받아온다.
아래는 해당 API 의 샘플 코드를 활용해 볼 수 있는 링크이다.
https://developer.riotgames.com/apis#match-v5/GET_getMatchIdsByPUUID
Riot Developer Portal
developer.riotgames.com
아래의 링크에서 찾아볼 수 있는 API 를 통해(puuid 값을 URL 변수로 가지는 API 이다.) 해당하는 소환사의 가장 최근 부터 개발자가 지정해 놓은 숫자까지의 매치 id 값을 받아온다.
그렇게 받아온 매치 id 값을 활용해 이번엔 각 매치의 상세 정보를 받환하는 API 를 구동시킨다.
아래의 링크로 들어가면 매치 id 값으로 매치 상세 정보를 받을 수 있는 샘플 API 를 구동시켜 볼 수 있다.(matchId 값을 URL 변수로 가지는 API 이다.)
https://developer.riotgames.com/apis#match-v5/GET_getMatch
Riot Developer Portal
developer.riotgames.com
이와 같은 과정을 통해 각 매치의 상세 정보를 받아오면, 해당 정보에서 puuid 값을 통해 찾고자 하는 소환사의 상세 매치 데이터만을 분류한 후 또다시 K/D/A 기록, 얻은 골드 및 사용한 골드 기록, 승패 여부 등의 데이터들을 추출하여 데이터베이스에 저장함과 동시에 컨트롤러를 활용하여 화면에 표시하고자 하는 데이터들을 뷰 측에 전달해주는 방식으로 소환사 최근 전적 기록 표시 기능을 구현했다.
Riot 측에서 제공하는 Data Dragon 등을 활용한 전적 별 이미지 처리
각 매치에서 픽한 챔피언의 프로필 이미지, 골드 이미지, 매치 별 최종 아이템들의 이미지와 선택한 소환사 스펠의 이미지들은 모두 Riot 측에서 제공해주는 Data Dragon 정보들을 활용했다.
Data Dragon 의 경우 자체적으로 제공해주는 zip 파일이나 json 파일등을 통해 데이터 들을 참조해서 가져올 수 있을뿐만 아니라, 단순 링크 연결을 통해서도 원하는 이미지 또는 정보들을 받아올 수 있다.
이번에 구현한 LOL 의 전체 챔피언들의 이미지 정보와 각종 상세 정보 또한 Data Dragon 에서 URL 링크를 통해 가져올 수 있는 정보들이 있었기 때문에 완성할 수 있었다.
- championController.java
try {
urlstr = "http://ddragon.leagueoflegends.com/cdn/11.16.1/data/ko_KR/champion.json";
rioturl = new URL(urlstr);
urlconnection = (HttpURLConnection)rioturl.openConnection();
urlconnection.setRequestMethod("GET");
br = new BufferedReader(new InputStreamReader(urlconnection.getInputStream(),"UTF-8"));
String result = "";
String line;
while((line=br.readLine())!= null) {
result = result + line;
}
JSONParser jsonParser = new JSONParser();
JSONObject k = (JSONObject) jsonParser.parse(result);
JSONObject data = (JSONObject) k.get("data");
Iterator iter = data.keySet().iterator();
List<String> champList = new ArrayList<String>();
String imgPath = "http://ddragon.leagueoflegends.com/cdn/11.16.1/img/champion/";
while(iter.hasNext()) {
champList.add((String)iter.next());
}
model.addAttribute("champList", champList);
model.addAttribute("imgPath", imgPath);
}catch(Exception e) {
e.printStackTrace();
}
- SummonerController.java
for (int i = 0; i < matchDataDTOList.size(); i++){
// 구매한 아이템들 이미지 처리
List<String> itemImageList = new ArrayList<>();
JSONObject jsonObject = new JSONObject((Map) matchDataDTOList.get(i));
jsonObject_itemList = new JSONObject(jsonObject.getString("itemList"));
String item0 = "http://ddragon.leagueoflegends.com/cdn/11.12.1/img/item/"+(Integer) jsonObject_itemList.getInt("item0")+".png";
String item1 = "http://ddragon.leagueoflegends.com/cdn/11.12.1/img/item/"+(Integer) jsonObject_itemList.getInt("item1")+".png";
String item2 = "http://ddragon.leagueoflegends.com/cdn/11.12.1/img/item/"+(Integer) jsonObject_itemList.getInt("item2")+".png";
String item3 = "http://ddragon.leagueoflegends.com/cdn/11.12.1/img/item/"+(Integer) jsonObject_itemList.getInt("item3")+".png";
String item4 = "http://ddragon.leagueoflegends.com/cdn/11.12.1/img/item/"+(Integer) jsonObject_itemList.getInt("item4")+".png";
String item5 = "http://ddragon.leagueoflegends.com/cdn/11.12.1/img/item/"+(Integer) jsonObject_itemList.getInt("item5")+".png";
String item6 = "http://ddragon.leagueoflegends.com/cdn/11.12.1/img/item/"+(Integer) jsonObject_itemList.getInt("item6")+".png";
itemImageList.add(item0);
itemImageList.add(item1);
itemImageList.add(item2);
itemImageList.add(item3);
itemImageList.add(item4);
itemImageList.add(item5);
itemImageList.add(item6);
String sendItemImage = "itemlist_List"+i;
model.addAttribute(sendItemImage, itemImageList);
// 사용한 소환사 스펠 이미지 처리
List<String> spellImageList = new ArrayList<>();
jsonObject_spellList = new JSONObject(jsonObject.getString("spellList"));
int keyValue1 = jsonObject_spellList.getInt("summoner1Id");
int keyValue2 = jsonObject_spellList.getInt("summoner2Id");
SpellDTO spellDTO1 = summonerService.selectSpellData(keyValue1);
SpellDTO spellDTO2 = summonerService.selectSpellData(keyValue2);
String spell1 = "http://ddragon.leagueoflegends.com/cdn/11.12.1/img/spell/"+spellDTO1.getSpellName()+".png";
String spell2 = "http://ddragon.leagueoflegends.com/cdn/11.12.1/img/spell/"+spellDTO2.getSpellName()+".png";
spellImageList.add(spell1);
spellImageList.add(spell2);
String sendSummonerSpell = "spellList_List"+i;
model.addAttribute(sendSummonerSpell, spellImageList);
// 선택한 챔피언 이미지 처리
String championName = jsonObject.getString("championName");
String championImagePath = "http://ddragon.leagueoflegends.com/cdn/11.12.1/img/champion/"+championName+".png";
String sendChampionImage = "championImage"+i;
model.addAttribute(sendChampionImage, championImagePath);
try{
apiURL = "https://ddragon.leagueoflegends.com/cdn/11.12.1/data/ko_KR/champion/"+championName+".json";
riotURL = new URL(apiURL);
urlConnection = (HttpURLConnection)riotURL.openConnection();
urlConnection.setRequestMethod("GET");
br = new BufferedReader(new InputStreamReader(urlConnection.getInputStream(), "UTF-8"));
String result="";
String line="";
while((line=br.readLine()) != null) {
result += line;
}
JSONObject jsonObject1 = new JSONObject(result);
JSONObject championList = jsonObject1.getJSONObject("data");
JSONObject championJSON = championList.getJSONObject(championName);
championName = championJSON.getString("name");
}catch (Exception e){
e.printStackTrace();
}
String sendChapionName = "championName"+i;
model.addAttribute(sendChapionName, championName);
}
화면에 이미지를 출력하는데 까지 성공했는데......성능은?
꽤나 오랜 시간을 들여서 이미지 경로를 컨트롤러에서 매핑해주는 것 부터 뷰 상에서 자바 코드를 작성하여 활용할 수 있는 JSP 의 장점을 이용하여 매핑된 경로에서 불러올 수 있는 이미지 정보를 화면상에 출력시키는 것 까지는 다행히 잘 수행해냈다.
하지만 구현을 하고 나서 보니 왠지 모르게 성능이 마음에 들지 않았다.
설계가 잘못 되는바람에 내부에서 처리하는 로직이 굉장히 많아져서 그런지 한번 소환사 최근 전적을 호출하고 나면 꽤나 시간이 지난 후에야 결과가 화면에 정상적으로 출력이 되는 것을 확인할 수 있었다.
한번 소환사 데이터 출력 요청을 보내고 나면 최소 10초 가까이는 기다려야 그 결과를 화면상으로 보여주는 것이다.
OP.GG 와 같은 다른 LOL 정보 웹 사이트를 보면 그곳에서는 모든 소환사 데이터 정보들을 자체적으로 데이터베이스에 모두 저장해두고 있는건지 결과가 굉장히 빠르게 출력되는 것을 볼 수 있었는데, 현재 프로젝트의 경우 마이페이지 에서 최근 전적을 호출하는 경우를 제외하고는 소환사 최근 전적을 호출할 때 데이터베이스에 결과를 저장하고 있지 않기 때문에 데이터를 호출할 때마다 계속 복잡한 작업이 반복되서 그런일이 발생하는 것인지, 그렇지 않으면 Data Dragon 을 통해서 매핑된 이미지 경로를 불러오는 과정이 오래 걸려서 그런건지는 알 수 없는 일이다.
사실 더 큰 문제는 전자가 문제이든 후자가 문제이든 지금의 역량으로서는 해결할 방법을 모르겠다는 것이다.
전자가 문제라면 설계를 어떤부분을 어떻게 바꿔야 하는지가 의문이고 후자가 문제라면 서버내에 필요한 이미지들을 모두 저장해두고 필요한 이미지를 그때그때 맞게끔 찾아서 뷰 쪽으로 전달해주어야 할 수도 있는데, 지금 상태에서 그런 방식으로 이미지를 처리하자니 코드를 전체적으로 모두 바꿔야 해서 굉장히 난감해진다.
그래도 일단 기능 자체는 원하는 대로 잘 동작하고 있으니 이번 프로젝트에서는 이 정도로 마무리 짓는게 어떤가 싶다.
여기서 성능을 더 늘릴수 있는 방법이 있다면 그건 아마 취업한 이후 개발자로서 커리어를 쌓기 시작하면서 배우게 되지 않을까 싶다.
* 소환사 최근 전적 객체 클래스 다이어그램
'프로젝트 > 협업' 카테고리의 다른 글
Pro.gg - 프로젝트 회고록(7) : 게시판 글 작성 및 댓글,답글 작성 (0) | 2021.10.26 |
---|---|
Pro.gg - 프로젝트 회고록(6) : 팀 구성 및 매칭 (0) | 2021.10.22 |
Pro.gg - 프로젝트 회고록(4) : 소환사 정보 - 1 (0) | 2021.10.19 |
Pro.gg - 프로젝트 회고록(3) : 회원 정보관리 (0) | 2021.10.14 |
Pro.gg - 프로젝트 회고록(2) : 악재 (0) | 2021.10.11 |