사용할 메이플스토리api(GetCharacterInfoByAccountID) 정보
http://api.maplestory.nexon.com/soap/maplestory.asmx?op=GetCharacterInfoByAccountID
MapleStory 웹 서비스
MapleStory 전체 작업 목록을 보려면 여기를 클릭하십시오. GetCharacterInfoByAccountID 테스트 테스트 폼은 로컬 컴퓨터의 요청에만 사용할 수 있습니다. SOAP 1.1 다음은 샘플 SOAP 1.1 요청 및 응답입니다.
api.maplestory.nexon.com
Request
링크에 들어가보면, 해당 API를 사용하기 위해서는 `Content-Length`와 `AccountID`값이 필요하다는 걸 알 수 있다.
`Content-Length`는 SOAP API 요청할 때 쓰는 xml data의 실제 byte 길이,
`AccountID`는 메이플스토리 공식 홈페이지에서 확인 가능한 값이다.
AccountID 확인 방법
내가 알아낸 방법은 두 가지가 있다.
첫 번째: 마이메이플(내정보 관리)에서 확인하는 방법
- 메이플스토리 공식 홈페이지에 접속, 로그인
- 마이메이플(내정보 관리)에 접속
- 대표캐릭터 표시 영역 밑쪽에 [캐릭터 정보 더보기>] 클릭
- 캐릭터정보 페이지에서 마우스 우클릭 -> 페이지 소스 코드 보기
- `char_custom_sel` 로 페이지 내에서 검색
- <option value="">메이플ID</option> 아래 쪽에 하나 더 있는 option의 value가 accountID
두 번째: 대표캐릭터 변경 페이지에서 확인하는 방법
- 메이플스토리 공식 홈페이지에 접속, 로그인
- 대표캐릭터 변경 페이지에 접속
- 마우스 우클릭 -> 페이지 소스 코드 표시
- 페이지 내에서 `sel_mail_id`로 검색
- javascript코드 말고 HTML 태그로 쓰인 곳을 찾았다면 그곳의 value가 accountID
Response
요청값을 알았다면 이제 반환값을 알아볼 차례이다. soap api이기 때문에 xml형식으로 반환된다. postman으로 요청 후 돌아온 값을 보자면...
<?xml version="1.0" encoding="utf-8"?>
<soap:Envelope xmlns:soap="http://www.w3.org/2003/05/soap-envelope" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<soap:Body>
<GetCharacterInfoByAccountIDResponse xmlns="https://api.maplestory.nexon.com/soap/">
<GetCharacterInfoByAccountIDResult>
<xs:schema id="NewDataSet" xmlns="" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
<xs:element name="NewDataSet" msdata:IsDataSet="true" msdata:UseCurrentLocale="true">
<xs:complexType>
<xs:choice minOccurs="0" maxOccurs="unbounded">
<xs:element name="UserInfo">
<xs:complexType>
<xs:sequence>
<xs:element name="AvatarImgURL" type="xs:string" minOccurs="0" />
<xs:element name="WorldName" type="xs:string" minOccurs="0" />
<xs:element name="CharacterName" type="xs:string" minOccurs="0" />
<xs:element name="Lev" type="xs:short" minOccurs="0" />
<xs:element name="Exp" type="xs:long" minOccurs="0" />
<xs:element name="Job" type="xs:string" minOccurs="0" />
<xs:element name="JobDetail" type="xs:string" minOccurs="0" />
<xs:element name="Pop" type="xs:int" minOccurs="0" />
<xs:element name="TotRank" type="xs:int" minOccurs="0" />
<xs:element name="WorldRank" type="xs:int" minOccurs="0" />
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:choice>
</xs:complexType>
</xs:element>
</xs:schema>
<diffgr:diffgram xmlns:msdata="urn:schemas-microsoft-com:xml-msdata" xmlns:diffgr="urn:schemas-microsoft-com:xml-diffgram-v1">
<NewDataSet xmlns="">
<UserInfo diffgr:id="UserInfo1" msdata:rowOrder="0" diffgr:hasChanges="inserted">
<AvatarImgURL>http://avatar.maplestory.nexon.com/Character/JBCLMLOOKMCJBKIAMAFMOHKCKBDDKCJHIEKJNODEPPPNENBNPHPOMHEDINLAIABGDBMAHDMKGGEMAAMKIGAMMENBDDPINMCMCGJAMDHKLCAMDDBGJJMBNAGGNNCEGOHHKDBKLLKJNDCGBAOAJCFJHMCMPLLOKLEKOJDANPEDFKHLMBJMIBIHKGAEOIFMANPMNAMHBDKJLLOBGACHBMKONMGEGKCCNHPBCEPEBEAJJMIKHMJOPAAAMNEFCJBPLBNE.png</AvatarImgURL>
<WorldName>리부트</WorldName>
<CharacterName>백에</CharacterName>
<Lev>245</Lev>
<Exp>294024963660</Exp>
<Job>해적</Job>
<JobDetail>바이퍼</JobDetail>
<Pop>6</Pop>
<TotRank>38309</TotRank>
<WorldRank>31186</WorldRank>
</UserInfo>
</NewDataSet>
</diffgr:diffgram>
</GetCharacterInfoByAccountIDResult>
</GetCharacterInfoByAccountIDResponse>
</soap:Body>
</soap:Envelope>
이렇게 되어있기 때문에, 내가 필요한 값(value)의 키값(key)이 다음과 같음을 알 수 있다.
- AvatarImgURL
- WorldName
- CharacterName
- Lev
- Exp
- Job
- JobDetail
- Pop
- TotRank
- WorldRank
자체 API 만들기
method | endpoint | request | response |
get | /v1/maplestory/representative-character/:accountId | - |
{
"t_character": {
"WorldName": "리부트",
"CharacterName": "백에",
"Lev": 245,
"Exp": 294024963660,
"Pop": 6,
"TotRank": 38309,
"WorldRank": 31186,
"jobId": 12
}
}
|
대표캐릭터 정보를 xml로 전달하는 메이플스토리 API에 직접 요청하지 않고 중간에 끼워넣어 json으로 받고싶을 때 쓸 수 있다.
`t_character` 테이블 정의를 할 때 굳이 Job, JobDetail을 넣어야하나... 싶어서 직업은 JobInfo enum으로 뺐기 때문에, 여러 라이브러리의 힘을 빌려서 이런 느낌으로 만들어봤다.
참고로 dol-maplestory은 `t_character`의 값을 json 객체로 직렬화해서 반환한다.
`t_character`의 구조는 이렇게 되어있는데, avatar_img_url, character_name, exp, lev, pop, tot_rank, world_name, world_rank는 xml response의 key값을 파스칼에서 스네이크 표기법으로 바꾼 것이다.
mysql> show columns from t_character;
+----------------+--------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+----------------+--------------+------+-----+---------+----------------+
| id | bigint(20) | NO | PRI | NULL | auto_increment |
| avatar_img_url | varchar(255) | YES | | NULL | |
| character_name | varchar(255) | NO | | NULL | |
| clearable_boss | varchar(255) | YES | | NULL | |
| exp | bigint(20) | YES | | NULL | |
| job_id | int(11) | YES | | NULL | |
| lev | int(11) | YES | | NULL | |
| pop | int(11) | YES | | NULL | |
| tot_rank | int(11) | YES | | NULL | |
| world_name | varchar(255) | YES | | NULL | |
| world_rank | int(11) | YES | | NULL | |
| user_id | bigint(20) | YES | MUL | NULL | |
+----------------+--------------+------+-----+---------+----------------+
다른 게 있다면 3개 정도
- id
- 캐릭터 고유 아이디. 넥슨쪽 캐릭터 아이디를 쓰는 것도 좋겠지만, 어떻게 찾아낼지 그것도 고민이고 구분만 할 수 있으면 됐기 때문에 그냥 따로 정의했다.
- clearable_boss
- 캐릭터가 깰 수 있는 보스를 알 수 있는 필드
- 1_1/2_1/10_6 처럼 저장될 예정인데, 아래와 같이 해석할 수 있다
- boss id 1에 대해 1명 입장해서 클리어
- boss id 2에 대해 1명 입장해서 클리어
- boss id 10에 대해 6명 입장해서 클리어
- boss id는 BossInfo enum을 참고
- user_id
- 그래도 뭘 만들려면 회원가입은 있어야하지 않겠나... 싶어서 만든 `t_user` 테이블의 primary key
- nexon maplestory accountID랑은 다른 값이다
- 메이플스토리는 거의 필수로 유저 한 명이 캐릭터 45개쯤은 키워야하는 게임이기에 캐릭터마다의 할일을 유저에게 보여줄 수 있으면 좋겠다 싶어서 추가했다
알게된 것
1.
@JsonProperty("name")
을 사용해서 직렬화/역직렬화시의 키값을 지정할 수 있다
2.
@JsonCreator
public TCharacter(
@JsonProperty("AvatarImgURL") String avatarImgUrl,
@JsonProperty("WorldName") String worldName,
@JsonProperty("CharacterName") String characterName,
@JsonProperty("Lev") Integer lev,
@JsonProperty("Exp") Long exp,
@JsonProperty("JobDetail") String jobDetail,
@JsonProperty("Pop") Integer pop,
@JsonProperty("TotRank") Integer totRank,
@JsonProperty("WorldRank") Integer worldRank
){
this.avatarImgUrl = avatarImgUrl;
this.worldName = worldName;
this.characterName = characterName;
this.lev = lev;
this.exp = exp;
this.jobId = JobInfo.getJobInfoByJobDetail(jobDetail).getId();
this.pop = pop;
this.totRank = totRank;
this.worldRank = worldRank;
}
생성자 위에 붙여 역직렬화할 때 사용할 수 있다.
3.
@JsonRootName("t_character")
는 Json객체의 주체를 알 수 있도록 할 때 사용한다. entity class위에 정의.
사용하기 위해선 application.propertes에 이하의 설정을 추가할 필요가 있다.
spring.jackson.serialization.wrap-root-value=true
4.
ObjectMapper objectMapper = new ObjectMapper().configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
ObjectMapper를 인스턴스화할 때 `configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false)`
를 추가함으로 Mapper class에 없는 properties가 있을 경우, 에러를 발생시키지 않고 스킵할 수 있다.
다음 할 일
Jsoup를 사용한 웹페이지 크롤링.. 이라기보다 캐릭터 정보 긁어내기
'memo' 카테고리의 다른 글
ssafy 10기 합격 (2) | 2023.06.24 |
---|---|
Cannot find a merge base between danger_base and danger_head (0) | 2022.08.18 |
git local branch 일괄 삭제 (0) | 2022.08.18 |
Json PropertyNamingStrategy (0) | 2022.06.10 |
Jsoup를 이용한 캐릭터 정보 탐색 (0) | 2022.06.09 |