사용할 메이플스토리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 확인 방법

내가 알아낸 방법은 두 가지가 있다. 

 

첫 번째: 마이메이플(내정보 관리)에서 확인하는 방법

  1. 메이플스토리 공식 홈페이지에 접속, 로그인
  2. 마이메이플(내정보 관리)에 접속
  3. 대표캐릭터 표시 영역 밑쪽에 [캐릭터 정보 더보기>] 클릭
  4. 캐릭터정보 페이지에서 마우스 우클릭 -> 페이지 소스 코드 보기
  5. `char_custom_sel` 로 페이지 내에서 검색
  6. <option value="">메이플ID</option> 아래 쪽에 하나 더 있는 option의 value가 accountID

 

두 번째: 대표캐릭터 변경 페이지에서 확인하는 방법

  1. 메이플스토리 공식 홈페이지에 접속, 로그인
  2. 대표캐릭터 변경 페이지에 접속
  3. 마우스 우클릭 -> 페이지 소스 코드 표시
  4. 페이지 내에서 `sel_mail_id`로 검색
  5. 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 -

대표캐릭터 정보를 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개 정도

  1. id
    • 캐릭터 고유 아이디. 넥슨쪽 캐릭터 아이디를 쓰는 것도 좋겠지만, 어떻게 찾아낼지 그것도 고민이고 구분만 할 수 있으면 됐기 때문에 그냥 따로 정의했다. 
  2. clearable_boss
    • 캐릭터가 깰 수 있는 보스를 알 수 있는 필드
    • 1_1/2_1/10_6 처럼 저장될 예정인데, 아래와 같이 해석할 수 있다
      • boss id 1에 대해 1명 입장해서 클리어
      • boss id 2에 대해 1명 입장해서 클리어
      • boss id 10에 대해 6명 입장해서 클리어
    • boss id는 BossInfo enum을 참고
  3. 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

+ Recent posts