Dev Note/JAX-WS (SOA) 2008.03.06 13:51


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/ 여기를 참고하세요.

신고

Dev Note/JAX-WS (SOA) 2008.03.05 21:19


JAXB (1) 에서 JAXB란 무엇인가에 대해 간략하게 알아보았다.
여기서는 JAXB에 포함되어 있는 xjc (Binding Compiler)를 이용하여 XML Schema를 가지고 정의 된 데이터 모델을 표현할 수 있는 Java Interfaces & Classes를 생성하는 것에 대해 다룬다.

먼저 JAXB Interfaces & Classes를 생성하기 위한 간단한 XML Schema를 만들어 보자.
정의 하고자 하는 XML Schema는 간단하게 회사를 정의 했는데, 회사와 팀을 정의하고, 회사에는 하나 이상의 팀이 속한다는 구조이다.

   <?xml version="1.0"?>
   <xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema">
      <xsd:element name="compony">
         <xsd:complexType>
            <xsd:sequence minOccurs="1" maxOccurs="unbounded">
               <xsd:element name="team">
                  <xsd:complexType>
                     <xsd:attribute name="name"/>
                  </xsd:complexType>
               </xsd:element>
            </xsd:sequence>
            <xsd:attribute name="name"/>
            <xsd:attribute name="address"/>
         </xsd:complexType>
      </xsd:element>
   </xsd:schema>

도식적으로 표현하면 아래와 같이 나타난다. (XmlSpy Enterprise 2008을 이용했음)

사용자 삽입 이미지

[ jaxb_sample.xsd 도식화 된 그림 ]

그럼 데이타 구조를 정의 한 XML Schema를 생성했으니, Binding Compiler (xjc)를 이용하여 Java Interfaces 또는 Classes를 생성해 보자. 생성에 앞서 먼저 Binding Compiler가 무엇인지 간단하게 설명을 하면

-- Binding Compiler (xjc)
XML Schema를 가지고, Schema에 의해 정의 된 데이터 모델을 표현할 수 있는 Java Interfaces 또는 Classes을 생성해 주는 Compiler를 말한다.
xjc는 JAXB를 다운받아 설치를 하면 bin 밑의 xjc.bat, xjc.sh를 이용하면 된다.

   Usage: xjc [-options ...] <schema file/URL/dir> ... [-b <bindinfo>] ...

* xjc 옵션 설명 (자주 사용되는 것) *
-d <dir> : 저장 된 Directory를 지정
-p <package> : Compile 되어 나오는 Interfases & Classes의 Package를 지정
-classpath <arg> : 실행에서 사용 할 classpath

 다음의 코멘드 라인 구문을 사용하여 Binding Compile을 해보자.

   xjc -p com.junducki.blog.jaxb -d D:\goorm\project\blog\src jaxb_sample.xsd

결과는 아래와 같이 나오며, D:\goorm\project\blog\src 아래에 com.junducki.blog.jaxb package로 Interfaces & Classes 들이 생성되어 있는 것이 확인이 될 것이다.

사용자 삽입 이미지

[ xjc를 실행 한 cmd 화면 ]

사용자 삽입 이미지

[ xjc 실행 결과 생성 된 Java Interfases & Classes ]


이제 JAXB를 이용하여 XML을 Java Object로 Java Object에서 XML로 변환하기 위한 준비가 완료 되었다. 다음에는 marshal과 unmarshal을 이용하여 XML과 Java Object의 변환 과정을 다루기로 한다.

신고

Dev Note/JAX-WS (SOA) 2008.03.05 20:29

-- JAXB 란 ?
XML은 이제 데이터를 표현하는 표준이며, Java Object를 XML로 나열할 때 사용하는 다양한 XML 기술들이 개발되어 왔다. 그 중에서 Java 개발자들에게 익숙한 두가지 기본 기술은 Simple API for XML (SAX)과 Document Object Model (DOM) API's 였다. 그러나 종종 프로그래머들은 즉각적인 테스트에 좀 더 특징적으로 적용할만한 기술을 필요로 하며, 이 경우 Object Data를 나열하는데 좀 더 간단한 XML 기불을 원하게 되어 JAXB가 나오게 되었다.
"Java Architecture for XML Binding"의 약자로 Java Web Services Development Pack의 표준이 되었다. XML Schema로부터 Java Class로 바인딩, XML로부터 Object를 직렬화(Serialization)하는 Unmarchalling 또는 이와 반대의 Marshalling을 수행 할 수 있도록 지원해주는 API를 말한다.
사용자 삽입 이미지

[ JAXB를 간략하게 설명 한 그림 ]

JAXB를 그림으로 나타내면 위와 같이 표현이 된다.

- Binding Compiler (xjc) : XML Schema를 가지고, Schema에 의해 정의 된 데이터 모델을 표현할 수 있는 Java Interfaces 또는 Classes을 생성해 주는 Compiler
- Schema-Derived Classes & Interfaces : XML Schema에 의해 정의 된 데이터 모델을 표현할 수 있는 Java Interface & Classes
- marshal : Java Object를 XML Docuement로 변환
- unmarshal : XML Document를 Java Object로 변환

JAXB에 대해 좀더 자세히 알고싶거나, 다운을 원한다면 https://jaxb.dev.java.net/jaxb20-fcs/으로 가능하다.
신고