엔티티에 대한 참조는 ';' 구분자로 끝나야 합니다

이종완·2022년 2월 10일
0

개발이야기

목록 보기
1/12
post-thumbnail

개요

残高照会APIで連続して業務エラーが得ている連携がございます。
こちら弊社側で対応必要でしょうか?

당행 API를 사용하는 외부 벤더로부터 오랜만에 연락이 왔다.

잔고조회 API가 연속으로 실패하는 특정 계좌가 있는데 아무리봐도 니네 잘못이니 확인 부탁한다는 내용이었다.

정상적으로 리스폰스200이 처리된 것을 보면 통신 장애는 아니었다.

그러나 서버 로그에서는, javax.xml.bind.UnmarshalException
(더 정확히는, org.xml.sax.SAXParseException) 오류를 확인할 수 있었다.

잔고 조회 API의 경우, 내가 담당하는 대외계 OPEN API 시스템을 경유하여 코어 뱅킹 시스템에서 고객 데이터를 가져온다.

XML 포맷으로 대외계에 데이터를 가져오게 되는데, 해당 고객만 왜 자꾸 오류나는지 이유를 찾고, 문제를 해결해야 했다.

문제

UnmarshalException
특정 고객의 데이터 XML 스트링의 unmarshal 및 역직렬화(자바객체로 변환) 불가능

원인

고객 정보 데이터에 XML 예약문자 '&'가 들어있는 것이 원인이었다
기업 고객이라서 고객 이름에 &가 들어있었다. ex) 株式会社 asdf & asdf
고객 데이터에서 &를 일괄제거 후 시뮬레이션하니 정상 동작하는 것을 확인할 수 있었다.

XML 예약문자

다음 문자들은 XML의 태그와 entity를 표시하는 문자로, 내부에서는 그대로 사용할 수 없다
& < > ' "

방법

  1. XML 스트링에서 예약 문자들을 다음과 같이 변환한다

&&amp;
<&lt;
>&gt;
'&apos;
"&quot;

株式会社 asdf &amp; asdf

  1. 혹은 CDATA를 이용하여 문자를 통째로 파싱한다

<![CDATA[株式会社 asdf & asdf]]>

예시

before

<data>
	<name> 株式会社 asdf & asdf </name>
</data>

after

<data>
	<name> 株式会社 asdf &amp; asdf </name>
</data>

after

<data>
	<name><![CDATA[ 株式会社 asdf & asdf ]]></name>
</data>

참고사항: String replace에 관하여

(org.apache.commons.lang.StringUtils.replace와 비교 시)
jdk8에서 String.replace 또는 replaceAll의 퍼포먼스가 약간 떨어진다고 한다.

jdk 버전에 따라 외부 유틸 사용을 고민해보는것도 유념해야겠다.
잔고 조회 api 마이크로 서비스는 jdk8로 되어 있으니 apache의 StringUtils를 사용하는 것이 성능 상 유리할 것 같다.
그래도 추후 확장성이라던가 jdk 버전업을 고려하면 String.replace를 사용하는 것도 좋은 선택이지만...언제가 될 지 모르니 고민이 커져만 간다.

(jdk9의 String.replace 성능은 apache.StringUtils.StringUtils와 유사,
jdk13의 String.replace 성능이 apache.StringUtils.StringUtils보다 우수하다고 한다.)

[참고] https://stackoverflow.com/questions/16228992/commons-lang-stringutils-replace-performance-vs-string-replace

profile
안녕하세요...

0개의 댓글