JAXB (2) - XML Schema를 Java Interfaces & Classes로 Binding Compile 하기에서 XML Schema로 정의 되는 데이터를 Binding 하기 위한 Java Interfaces & Classes로 Binding Compile 하는 법에 대해 알아봤습니다.
그럼 이번에는 Binding 된 Interfaces와 Classes를 이용하여 Java Object를 XML 표현으로 marchal하는 것과 XML 표현을 Java Object로 unmarshal 하는 것에 대해 알아본다.
-- marshal
Binding Interfases & Classes로 처리된 Content Tree를 하나 이상의 XML 표현으로 직렬화시키는 것을 말한다. Content Tree는 정렬화되기 전에 유효성 검사를 하게 된다.
-- unmarshal
XML 표현을 Source Schema 조건들에 따라서 Binding Interfases & Classes의 Java Object로 비정렬화시키는 것을 말한다. JAXB에서는 파일이나 문서형태의 소스 만이 아니라 DOM 노드, String Buffer, SAX 소스 등에 대한 처리도 가능하다.
-- validation
유횬성 검사는 XML 문서가 스키마에 표현되어 있는 모든 제약 조건을 만족시키는지를 확인합니다. JAXB 1.0은 비정렬화를 실시할 때 유효선 검사를 할 수 있도록 해주며, 필요할 경우에 JAXB Content Tree에 대해서도 검사를 할 수 있도록 해줍니다. JAXB 2.0은 정렬화 또는 비정렬화 할 때 모두 유효성 검사를 제공하고 있습니다.
웹 서비스 처리 모델은 데이터를 읽을 때는 엄격하지 않게 처리하고, 쓸 때는 엄격하게 처리합니다. 그러한 모델을 위해서는 유효성 검사는 정렬화 시기에 이루어져서 JAXB 형식으로 문서를 수정할 때 XML 문서가 잘못 되었는지를 확인할 수 있도록 해야 합니다.
-- Unmarshalling 하기
다음은 XML 파일을 JAXB 생성 인스턴스로 비정렬화(unmarshalling)하는 것에 대한 예제와 간단한 설명이다.
package com.junducki.blog.jaxb.test;
import java.io.File;
import java.util.Iterator;
import java.util.List;
import javax.xml.bind.JAXBContext;
import javax.xml.bind.JAXBException;
import javax.xml.bind.Unmarshaller;
import com.junducki.blog.jaxb.Company;
public class UnmarshallingTest {
public static void main(String[] args) {
try {
JAXBContext jc = JAXBContext.newInstance("com.junducki.blog.jaxb");
Unmarshaller unmarshaller = jc.createUnmarshaller();
// unmarshaller.setValidating(true);
Company company = (Company) unmarshaller.unmarshal(new File(
"E:/temp/blog/jaxb/jaxb_company_sample.xml"));
System.out.println("Company Info :: NAME[" + company.getName() + "], ADDRESS[" +
company.getAddress() + "], TEAM_COUNT[" + company.getTeam().size() + "]");
List<Team> teamList = company.getTeam();
Iterator iter = teamList.iterator();
while (iter.hasNext()) {
Team team = (Team) iter.next();
System.out.println("Team Info :: NAME[" + team.getName() + "]");
}
} catch (JAXBException e) {
e.printStackTrace();
}
}
}
먼저 com.junducki.blog.jaxb package를 사용하여 JAXBContext를 생성한다. com.junducki.blog.jaxb package에는 Binding Compile의해 생성 된 Java Interfaces & Classes들이 포함되어 있으며, JAXBContext가 Unmarshaller Object를 생성하기 위해 사용한다.
JAXBContext jc = JAXBContext.newInstance("com.junducki.blog.jaxb");
XML 표현을 Java Object로 비직렬화하기 위한 Unmarshaller를 생성한다. 여기서 setValidating(boolean)은 Validate 수행 여부를 나타내며, JAXB 1.0에서는 함수를 이용해 설정이 가능했으나, JAXB 2.0에서는 Deprecated 되었다.
Unmarshaller unmarshaller = jc.createUnmarshaller();
// unmarshaller.setValidating(true);
JAXBContext에서 생성한 Unmarshaller를 이용하여 XML 파일을 비직렬화 하기 위해 unmarshal() 함수를 이용한다. unmarshal() 함수는 여기서 사용한 파일 이외에 URL, Source, Node 등 다양한 것을 지원한다.
Company company = (Company) unmarshaller.unmarshal(new File(
"E:/temp/blog/jaxb/jaxb_company_sample.xml"));
예제의 다음 부분은 Ummarshalling 된 Object의 내용을 간단히 System.out으로 출력하는 부분이다.
-- Marshalling 하기
다음은 Ummarshalling의 반대인 Java Object를 XML 파일로 직렬화하는 것에 대한 간단한 예제와 설명이다.
package com.junducki.blog.jaxb.test;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import javax.xml.bind.JAXBContext;
import javax.xml.bind.JAXBException;
import javax.xml.bind.Marshaller;
import com.junducki.blog.jaxb.Company;
import com.junducki.blog.jaxb.ObjectFactory;
import com.junducki.blog.jaxb.Company.Team;
public class MarshallingTest {
public static void main(String[] args) {
try {
ObjectFactory objFactory = new ObjectFactory();
Company company = objFactory.createCompany();
company.setName("Test Company");
Team team1 = objFactory.createCompanyTeam();
team1.setName("Test Team 1");
Team team2 = objFactory.createCompanyTeam();
team2.setName("Test Team 2");
company.addTeam(team1);
company.addTeam(team2);
JAXBContext jc = JAXBContext.newInstance("com.junducki.blog.jaxb");
Marshaller marshaller = jc.createMarshaller();
marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, new Boolean(true));
marshaller.marshal(company, new FileOutputStream(
"E:/temp/blog/jaxb/jaxb_company_marshal_sample.xml"));
} catch (JAXBException e) {
e.printStackTrace();
} catch (FileNotFoundException e) {
e.printStackTrace();
}
}
}
Marshalling 하기 위한 Java Content Tree를 생성한다. Tree Element의 생성은 xjc에 의해 생성 된 ObjectFactory를 이용하여 생성하며, Company의 addTeam(Team teamElement) 함수는 xjc에 의해 생성 된 Company Class에 있는 것이 아니고, 추가 된 함수이다.
Java Content Tree를 생성했으면 Marshalling을 위해 JAXBContext를 Unmarshalling 때와 마찬가지로 생성하고, Java Content Tree를 XML 표현으로 직렬화하기 위해 Marshaller를 생성한다.
Marshaller marshaller = jc.createMarshaller();
// Marshalling 된 XML 표현을 Formatting 하기 위한 설정
marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, new Boolean(true));
마지막으로 marshaller는 marshal() 함수를 이용하여 생성 된 Java Content Tree를 XML 파일로 직렬화하여 쓴다. marshal() 함수도 unmarshal() 함수와 마찬가지로 여러 형태를 지원한다.
이상 여기까지가 JAXB에 대해 3부로 거쳐 알아봤습니다. 여기 소개한 내용은 JAXB 중 극히 일부에 불과하니 좀더 알고 싶은 분들은 https://jaxb.dev.java.net/jaxb20-fcs/ 여기를 참고하세요.