MAKE IT SIMPLE

[Gradle] XSD, WSDL 파일로 JAXB 클래스 생성하기 본문

Gradle

[Gradle] XSD, WSDL 파일로 JAXB 클래스 생성하기

punchlips 2021. 1. 28. 18:49

Spring Boot 프로젝트에서 gradle build script를 사용하여 스키마 정의 파일을 변환한 자바 오브젝트(jaxb classes)를 생성해줄 수 있다.

 

build.gradle에 사용자 정의 task를 등록해주면 프로젝트 빌드시 지정한 위치에 jaxb 클래스가 자동으로 생성된다.

https://as-you-say.tistory.com/141 - Groovy 기본 문법을 공부하기 좋은 글이니 스크립트를 잘 모른다면 참고.

 

스키마 파일을 자바 클래스로 변환하는데 xjc 툴이 사용되는데 jaxb-xjc의 파라미터 속성은 다음과 같다.

 

Attribute Description required
schema 컴파일 할 스키마 파일 O
binding 스키마 파일에 적용될 외부 바인딩 파일 X
package 지정된 경우 생성된 코드는 해당 java 패키지 아래에 배치된다.
이  "-p" 명령 줄 스위치와 동일하다.
X
destdir 생성된 코드는 이 디렉토리 아래에 작성된다.
당신이  target="abc/def"와 package="org.acme" 이렇게 지정하는 경우, 다음 파일로 생성된다.  abc/def/org/acme

O
readonly true 로 지정된 경우 읽기 전용 모드에서 java 소스파일이 생성된다.
기본적으로 false 이다.
X
extension true 로 설정하면 XJC 바인딩 컴파일러가 확장 모드에서 실행된다.
그렇지 않으면 엄격한 준수 모드에서 실행된다.
X
catalog 외부 엔티티 참조를 분석하려면 카탈로그 파일을 지정해야 한다.
TR9401, XCatalog 및 OASIS XML 카탈로그 형식을 지원한다.
X
removeOldOutput 중첩 된 produces 요소와 쌍으로 사용된다.
이 속성 값을 yes 로 지정할 경우 XJC 바인딩 컴파일러가 소스 파일을 다시 컴파일 하기 전에 요소가 가리키는 파일이 모두 삭제된다.
X
source 사용할 스키마 컴파일러의 버전을 지정한다.
"1.0"또는 "2.0"이어야 한다. 생성 된 소스 코드는 JAXB 1.0 사양 또는 2.0 사양에 지정된 바인딩 규칙을 따른다.
X, default = "2.0"
language 컴파일 할 스키마 언어를 지정한다. 
지원되는 값은 "WSDL", "XMLSCHEMA"및 "WSDL" 이 있다.
대소 문자는 구분하지 않는다.
XMLSCHEMA

 

 


 

01 XSD → JAXB classes

 

1) task 설정 및 의존성 지정

- 의존성을 지정해 줄 때에는 task 이름의 group으로 지정해주어야 한다

 

//jaxb 등록
configurations {
    jaxb
}

dependencies {
     ......

    //jaxb의 의존성 지정

     jaxb group: 'com.sun.xml.bind' , name: 'jaxb-xjc' , version: '2.3.1'
     jaxb group: 'com.sun.xml.bind' , name: 'jaxb-impl' , version: '2.3.1'
     jaxb group: 'javax.xml.bind' , name: 'jaxb-api' , version: '2.3.1'
     jaxb group: 'org.glassfish.jaxb' , name: 'jaxb-core' , version: '2.3.0.1'
}

 

2) task 내용 작성

 

//사용자 정의 task : jaxb
task jaxb {

System.setProperty('javax.xml.accessExternalSchema', 'all')

def jaxbTargetDir = file("src/main/java/")

doLast {
        jaxbTargetDir.mkdirs() //디렉토리 생성
     ant.taskdef(
      name: 'xjc',
      classname: 'com.sun.tools.xjc.XJCTask',
            classpath: configurations.jaxb.asPath //의존성 사용
        )
     ant.jaxbTargetDir = jaxbTargetDir
  
     ant.xjc(
         destdir: '${jaxbTargetDir}',
            package: 'com.jaxb.test2',
            schema: 'src/main/resources/shiporder.xsd'
        )
    }
}

 

- 작업할 스키마 파일이 여러개이고, 파일별로 패키지를 나누어 줄거라면 다음과 같이 스크립트를 작성할 수 있다

 

task jaxb {
        System.setProperty('javax.xml.accessExternalSchema', 'all')
        def jaxbTargetDir = file('src/main/java')
  
        doLast {
  
        jaxbTargetDir.mkdirs()
  
        ant.taskdef(
            name: 'xjc',
            classname: 'com.sun.tools.xjc.XJCTask',
            classpath: configurations.jaxb.asPath //의존성 사용
        )
  
        ant.jaxbTargetDir = jaxbTargetDir
  
            def files  = file('src/main/resources/defaultModule').listFiles().sort()
      
            //파일별로 작업
      files.each{ File file -> 
                if(file.isFile()){
                    ant.loadfile(srcFile: file, property: file.name)
              
                    def name = (file.name).replace('.xsd', '').toLowerCase()
                    def packageName = (file.name).replace('.xsd', '')

                    ant.xjc(
                        destdir: '${jaxbTargetDir}',
                        package: "com.wings.cms.schema.module.$packageName",
                        schema: "src/main/resources/defaultModule/${name}.xsd"
                    )
                }
            }
        }
    }

 

3) task 연달아 수행하기

-task 를 연이어 실행하려면 task명.configure{ ....what to do...}를 써주면 된다

 

jaxb.configure { 

....next to do

}

 

4) task 실행 후 compileJava

- dependsOn은 task 간의 의존성을 설정한다. A.dependsOn B 일시, A가 B에 의존하게 되어 B 실행 후 A가 실행된다

 

 compileJava.dependsOn jaxb   

 

-build.gradle의 전체 스크립트는 다음과 같다

 

plugins {
    id 'org.springframework.boot' version '2.4.2'
    id 'io.spring.dependency-management' version '1.0.11.RELEASE'
    id 'java'
}

group = 'com.example'
version = '0.0.1-SNAPSHOT'
sourceCompatibility = '1.8'

repositories {
    mavenCentral()
}
//jaxb 등록
configurations {
    jaxb
}

dependencies {
    implementation 'org.springframework.boot:spring-boot-starter'
    testImplementation 'org.springframework.boot:spring-boot-starter-test'

    //jaxb의 의존성 지정
     jaxb group: 'com.sun.xml.bind' , name: 'jaxb-xjc' , version: '2.3.1'
     jaxb group: 'com.sun.xml.bind' , name: 'jaxb-impl' , version: '2.3.1'
     jaxb group: 'javax.xml.bind' , name: 'jaxb-api' , version: '2.3.1'
     jaxb group: 'org.glassfish.jaxb' , name: 'jaxb-core' , version: '2.3.0.1'
}

//사용자 정의 task : jaxb
task jaxb {
    System.setProperty('javax.xml.accessExternalSchema', 'all')
    def jaxbTargetDir = file("src/main/java/")
    doLast {
        jaxbTargetDir.mkdirs()
        ant.taskdef(
            name: 'xjc',
            classname: 'com.sun.tools.xjc.XJCTask',
            classpath: configurations.jaxb.asPath //의존성 사용
        )
        ant.jaxbTargetDir = jaxbTargetDir
  
        ant.xjc(
            destdir: '${jaxbTargetDir}',
            package: 'com.jaxb.test1',
            schema: 'src/main/resources/shiporder.xsd'
        )
    }
}

jaxb.configure {

   System.setProperty('javax.xml.accessExternalSchema', 'all')
    def jaxbTargetDir = file("src/main/java/")
    doLast {
        jaxbTargetDir.mkdirs()
        ant.taskdef(
            name: 'xjc',
            classname: 'com.sun.tools.xjc.XJCTask',
            classpath: configurations.jaxb.asPath //의존성 사용
        )
        ant.jaxbTargetDir = jaxbTargetDir
  
        ant.xjc(
            destdir: '${jaxbTargetDir}',
            package: 'com.jaxb.test2',
            schema: 'src/main/resources/shiporder.xsd'
        )
    }

}

compileJava.dependsOn jaxb

test {
    useJUnitPlatform()
}

 

5) Gradle Task 탭에서 프로젝트 우클릭 -> build -> build 

리프레쉬 해주면 지정한 디렉토리에 자바 클래스가 생성되었다

 

 

02 WSDL → JAXB classes

 

XSD와 같은 방식이지만 language 속성을 추가해주면 된다

 

 

테스트용 xsd, wsdl 파일은 첨부해놓았다. 삽질 끝!

 

test.wsdl
0.00MB

 

shiporder.xsd
0.00MB

Comments