Skip to content
I

iso20022lib

English | 한국어

iso20022lib-core (ISO20022 코어 모듈)
iso20022lib-spring (스프링 확장 모듈)
iso20022-editor (웹 기반 ISO20022 에디터)

개요

ISO20022 Message Handler Library는 Java 17 환경에서 ISO20022 표준 금융 전문을 쉽고 안전하게 다루기 위한 전용 프레임워크. 복잡하게 얽힌 XML/JSON 기반 전문 교환 로직을 간소화하고 전문 생성, 변환(마샬링/언마샬링), 검증을 통합 제공. 이를 통해 개발자는 비즈니스 로직 구현에 집중 가능하며, 표준 준수와 보안성을 손쉽게 확보.

핵심 요소

  1. ISO20022Message 🔗
  • 각 전문 타입(ACMT, PAIN 등)을 객체 지향적으로 추상화하여, 개발자가 필드를 직관적으로 접근하고 수정 가능.
  • XML/JSON 객체 간 변환, 스키마 기반 검증 로직, HMAC/해시 생성 등이 내장되어 금융 전문을 간단하고 안전하게 처리.
  • 빌더 패턴과 유형별 인스턴스 초기화 팩토리 메소드 제공으로 복잡한 메시지 구조를 간결하고 타입 안전하게 생성
  1. ISO20022Facade 🔗
  • 라이브러리의 파사드(Facade) 역할을 담당, 전문 생성(Create), 읽기(Read), 쓰기(Write) 과정을 단계적 빌더 패턴으로 일원화.
  • "타입 지정 → 템플릿/옵션 설정 → 빌드 실행" 흐름을 통해 설정 실수를 사전에 방지하고, 코드 가독성과 유지보수성 향상.
  • 헤더+본문(Envelope) 구조를 포함해 다양한 전문 시나리오를 단일 API로 일관성 있게 처리.
  1. ISO20022Type 🔗
  • ISO20022 전문 스키마 ID(예: acmt.007.001.05)에 대응하는 열거형(Enums) 으로, 약 700개 이상의 표준 타입을 체계적으로 관리.
  • 스키마 네임스페이스, 루트 엘리먼트 클래스, 버전 등 다양한 메타정보 제공, 개발 시점에서 전문 타입의 안전성 보장.
  • 전문 타입 검색과 자동 감지 기능으로, XML/JSON 내용을 바탕으로 해당 전문의 버전을 추론하거나 유효성 검사 가능.

주요 특징 및 이점

  • 직관적 전문 생성: 메시지별 builder() 메서드나 emptyInstance(), requiredInstance() 등을 활용하여 객체를 간단히 구성. 복잡한 중첩 구조도 체인 방식으로 명확하게 초기화.
  • 자동 검증 및 예외 처리: ISO20022 표준 스키마 기반 검증 로직으로 필드 누락이나 형식 오류를 빠르게 식별. 전용 예외 계층(ISO20022Exception.*)으로 오류 유형별 세분화 처리 용이.
  • 보안 기능 내장: XML 외부 엔티티(XXE) 공격 방지, HMAC 기반 무결성 검증 등이 적용되어 금융 전문 처리 시 발생할 수 있는 보안 취약점 감소.
  • 유연한 포맷 변환: XML/JSON 포맷 간 상호 변환 및 파일·문자열·스트림 단위 입출력 지원으로 다양한 통신 방식 대응.
  • 스프링 부트 연동: iso20022lib-spring 모듈을 통해 Spring Boot AutoConfiguration 제공, 환경 설정에 따른 전역 옵션 관리와 로깅, 트랜잭션 설정 자동화 지원.
  • 코드 생성 자동화: ISO20022 XSD에서 Java 클래스를 자동 생성해 버전 업데이트에 신속히 대응. 중복 클래스 충돌을 방지하도록 최적화된 패키지 구조 채택.

위 구성 요소들을 통해 ISO20022 Message Handler Library는 금융권에서 요구되는 전문 처리의 복잡도를 추상화하고, 개발 생산성과 표준 준수를 극대화. 추가 문서와 예제를 참고하면, 다양한 시나리오에서 라이브러리를 효과적으로 활용 가능.

문서 가이드

빠른 시작 가이드

환경 구성 🔗

Gradle

build.gradle에 의존성 추가:

repositories {
  maven {
    url = "https://nexus.innilabs.co.id/repository/maven-public/"
    credentials {
      username = "hanabank"
      password = "Hanabank2025"
    }
  }
}
dependencies {
  implementation 'com.innilabs:iso20022lib-core:0.6.6-SNAPSHOT'
  implementation 'com.innilabs:iso20022lib-spring:0.6.6-SNAPSHOT' // Spring Boot 연동 모듈 (선택)
}
Maven

pom.xml에 의존성 추가:

<repositories>
  <repository>
    <id>innilabs-nexus</id>
    <url>https://nexus.innilabs.co.id/repository/maven-public/</url>
  </repository>
</repositories>

<dependencies>
  <!-- ISO20022 library -->
  <dependency>
    <groupId>com.innilabs</groupId>
    <artifactId>iso20022lib-core</artifactId>
    <version>0.6.6-SNAPSHOT</version>
  </dependency>
  <dependency>
    <groupId>com.innilabs</groupId>
    <artifactId>iso20022lib-spring</artifactId>
    <version>0.6.6-SNAPSHOT</version>
  </dependency>
</dependencies>

<!-- ~/.m2/settings.xml -->
<settings>
  <servers>
    <server>
      <id>innilabs-nexus</id>
      <username>hanabank</username>
      <password>Hanabank2025</password>
    </server>
  </servers>
</settings>

Spring Auto Configuration (선택) 🔗

별도 설정이 없을 시 기본값 자동 적용

(iso20022lib-spring 모듈 필요)

iso20022:
  encoding: UTF-8
  xml:
    pretty-print: on
  json:
    pretty-print: off
  file:
    policy: fail
  envelope:
    body-prefix: "doc"
    header-prefix: "head"
    root-name: "envelope"
    xml:
      indentation: 4
      standalone: true
  validation:
    schema: false
  timezone: Asia/Jakarta
  hash-key: secretiso20022

기본 사용법

ISO20022Message 🔗

// 메시지 템플릿
ACMT01800104 emptyMsg = ACMT01800104.emptyInstance();       // 빈 객체
ACMT01800104 requiredMsg = ACMT01800104.requiredInstance(); // 필수 필드만 초기화
ACMT01800104 completeMsg = ACMT01800104.fullInstance();     // 전체 필드 초기화

// 빌더 사용 (Consumer 방식)
ACMT02300104 msg = ACMT02300104.builder()
    .withAssgnmt(assgnmt -> assgnmt
        .withMsgId("MSG001")
        .withCreDtTm(LocalDateTime.now())
    )
    .build();

// XML/JSON 역직렬화
ACMT02300104 msgFromXml = ACMT02300104.fromXML(xmlString);
ACMT02300104 msgFromJson = ACMT02300104.fromJSON(jsonString);
ACMT02300104 msgFromFile = ACMT02300104.fromFile("resources/message.xml", StringFormat.XML);

// 직렬화
String xml = msg.toXML();
String json = msg.toJson();
File file = msg.toFile("output.json", StringFormat.JSON);

// 스키마 검증
SchemaValidationResult result = msg.validate();
boolean isValid = result.isValid();

// 해시/HMAC
String hash = msg.toHash();
String hmac = msg.toHMAC();
MessageEnvelope (헤더 포함 복합 메시지)
// 복합 메시지 (헤더+본문) 빌더
MessageEnvelope envelope = MessageEnvelope.builder()
    .header(headerMessage)
    .body(businessMessage)
    .build();

// 역직렬화/역마샬링
MessageEnvelope fromXml = MessageEnvelope.fromXML(xmlString);
MessageEnvelope fromJson = MessageEnvelope.fromJSON(jsonString);
MessageEnvelope fromFile = MessageEnvelope.fromFile(new File("message.xml"), StringFormat.XML);

// 헤더/본문 접근
ISO20022Message<?> header = envelope.getHeader();
ISO20022Message<?> body = envelope.getBody();

// 직렬화/마샬링
String xml = envelope.toXML();
String json = envelope.toJSON();
File file = envelope.toFile("output_envelope.xml", StringFormat.XML);

// 검증
SchemaValidationResult res = envelope.validate();
boolean ok = res.isValid();

// 해시/HMAC
String hash = envelope.toHash();
String hmac = envelope.toHMAC();

ISO20022Facade 🔗

Fluent API 기반으로 ISO20022 메시지의 생성, 읽기, 쓰기 과정을 단순화. 다양한 설정 커스터마이징 제공

단계별 빌더 사용으로 실수 방지. 지정하지 않은 항목은 내부 기본값 적용.

// 메시지 생성
ISO20022Message<?> message = ISO20022Facade.create()
    .type(ISO20022Type.PAIN_001_001_09)
    .requiredInstance() // emptyInstance(), fullInstance() 등 대안
    .buildMessage();

// 메시지 읽기
ISO20022Message<?> messageFromFile = ISO20022Facade.read()
    .source(new File("message.xml"))
    .buildMessage();

// 문자열에서 메시지 읽기
ISO20022Message<?> messageFromString = ISO20022Facade.read()
    .source(xmlContent)
    .xmlFormat()                      // 생략 시 자동 감지, jsonFormat() 등 대안 
    .type(ISO20022Type.PAIN_001_001_09) // 생략 시 자동 감지
    .validation()                     // 생략 시 기본값, 스키마 검증 (skipValidation() 등 대안)
    .encoding(StandardCharsets.UTF_8) // 생략 시 기본값
    .buildMessage();

// 메시지 쓰기
String xmlString = ISO20022Facade.write()
    .message(message)
    .xmlFormat()
    .prettyPrint() // 생략 시 기본값, uglyPrint() 대안
    .buildString();

File outputFile = ISO20022Facade.write()
    .message(message)
    .xmlFormat()
    .overwriteIfExists() // 생략 시 기본값, skipIfExists(), failIfExists() 등 대안
    .buildFile("output.xml");
MessageEnvelope
MessageEnvelope envelope = ISO20022Facade.create()
    .type(ISO20022Type.PAIN_001_001_09)
    .requiredInstance()
    .buildEnvelopedMessage(ISO20022Type.HEAD_001_001_01);

// 복합 메시지 읽기
MessageEnvelope envelopeFromFile = ISO20022Facade.readEnveloped()
    .source(new File("envelope.xml"))
    .headerType(ISO20022Type.HEAD_001_001_01)
    .bodyType(ISO20022Type.PAIN_001_001_09)
    .validation() // 생략 시 기본값
    .encoding(StandardCharsets.UTF_8) // 생략 시 기본값
    .headerPrefix("header") // 생략 시 기본값
    .bodyPrefix("body")     // 생략 시 기본값
    .buildMessage();

ISO20022Facade.writeEnveloped()
    .message(envelope)
    .xmlFormat()
    .rootName("Envelope") // 생략 시 기본값
    .headerPrefix("AppHdr") // 생략 시 기본값
    .bodyPrefix("Document") // 생략 시 기본값
    .validation() // 생략 시 기본값
    .encoding(StandardCharsets.UTF_8)
    .buildFile("envelope.xml");

예외 처리 🔗

try {
    ISO20022Facade.read()
        .source(someXmlString)
        .validation()
        .buildMessage();
} catch (ISO20022Exception.SchemaValidationException e) {
    System.err.println("검증 실패: " + e.getMessage());
} catch (ISO20022Exception.MarshallingException e) {
    System.err.println("변환 실패: " + e.getMessage());
}

© 2025 INNILABS. All rights reserved.