MAKE IT SIMPLE
[Gradle] XSD, WSDL 파일로 JAXB 클래스 생성하기 본문
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 파일은 첨부해놓았다. 삽질 끝!
'Gradle' 카테고리의 다른 글
[Gradle] Jaxb2 Collection Setter 라이브러리 사용하기 (JAVA 11) (0) | 2021.04.28 |
---|---|
[Gradle] Java 11 에서 jaxb 라이브러리 사용하기 (0) | 2021.02.15 |