2011년 5월 23일 월요일

JAXB을 이용한 Object marshalling과 unmarshalling

이 글은 http://kr.sun.com/developers/techtips/e2004_1221.html#1 글을 기본으로 내용을 추가한 글입니다.
테스트를 위한 설치 내역
1. JWSDP(Java Web Service Development Pack) 1.4
2. J2SDK 1.4.2_06
3. Tomcat 5.0 (for JWSDP 1.4)
JWSDP을 설치 후 jaxb/lib와 jwsdp-shared/lib 디렉토리의 모든 jar 파일이 System Class Path 에 잡혀 있어야 하며 jaxb/bin 디렉토리는 System Path에 잡혀 있어야 한다.

JAXB 란?
“Java API for XML Binding”의 약자로 XML 스키마로부터 클래스 데이터를 바인딩, XML로부터 객체를 직렬화(Serialization)하거나(Unmarshalling) 이와 반대 작업(marshalling)을 수행 할 수 있도록 지원해준다.

JAXB를 이용한 Sample Program
Sample로 작성할 프로그램은 클라이언트가 사용자 정보를 서버에게 전송하면 서버측에서 사용자 권한 레벨을 지정하여 클라이언트에게 재 전송하는 샘플이다.

1. 전송 전문 XML 스키마 작성
“user.xsd” 파일 내용
<?xml version="1.0" encoding="UTF-8"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">
<xs:import namespace="http://www.w3.org/XML/1998/namespace"
schemaLocation="http://www.w3.org/2001/xml.xsd" />
<xs:element name="userinfo">
<xs:complexType>
<xs:sequence>
<xs:element name="name" type="xs:string" />
<xs:element name="age" type="xs:int" />
<xs:element name="phone" type="xs:int" />
<xs:element name="memberLevel" type="xs:string"/>
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:schema>

클라이언트와 서버간에 데이터 전송 XML의 스키마를 작성합니다. 스키마 작성은 XML 에디터 툴을 이용하거나 JBuilder, JDeveloper 등의 IDE 툴을 사용하시면 쉽게 작성할 수 있습니다.

2. XML 스키마로부터 클래스 생성
작성된 XML 스키마로부터 객체 마샤링과 언마샤링에 사용할 클래스를 축출합니다.
“xjc –p member.user.jaxb –d . user.xsd ”
생성된 클래스는 다음과 같습니다. 이를 컴파일 합니다.
member/user/jaxb/impl/JAXBVersion.java
member/user/jaxb/impl/UserinfoImpl.java
member/user/jaxb/impl/UserinfoTypeImpl.java
member/user/jaxb/impl/runtime/InterningUnmarshallerHandler.java
member/user/jaxb/impl/runtime/UnmarshallingEventHandlerAdaptor.java
member/user/jaxb/impl/runtime/DefaultJAXBContextImpl.java
member/user/jaxb/impl/runtime/ValidatorImpl.java
member/user/jaxb/impl/runtime/UnmarshallingContext.java
member/user/jaxb/impl/runtime/SAXUnmarshallerHandler.java
member/user/jaxb/impl/runtime/Util.java
member/user/jaxb/impl/runtime/UnmarshallingEventHandler.java
member/user/jaxb/impl/runtime/XMLSerializer.java
member/user/jaxb/impl/runtime/ValidationContext.java
member/user/jaxb/impl/runtime/PrefixCallback.java
member/user/jaxb/impl/runtime/ValidatableObject.java
member/user/jaxb/impl/runtime/UnmarshallableObject.java
member/user/jaxb/impl/runtime/SAXMarshaller.java
member/user/jaxb/impl/runtime/XMLSerializable.java
member/user/jaxb/impl/runtime/SAXUnmarshallerHandlerImpl.java
member/user/jaxb/impl/runtime/UnmarshallerImpl.java
member/user/jaxb/impl/runtime/ContentHandlerAdaptor.java
member/user/jaxb/impl/runtime/MarshallerImpl.java
member/user/jaxb/impl/runtime/ErrorHandlerAdaptor.java
member/user/jaxb/impl/runtime/AbstractUnmarshallingEventHandlerImpl.java
member/user/jaxb/impl/runtime/GrammarInfo.java
member/user/jaxb/impl/runtime/GrammarInfoFacade.java
member/user/jaxb/impl/runtime/Discarder.java
member/user/jaxb/impl/runtime/GrammarInfoImpl.java
member/user/jaxb/impl/runtime/NamespaceContext2.java
member/user/jaxb/impl/runtime/ValidatingUnmarshaller.java
member/user/jaxb/impl/runtime/NamespaceContextImpl.java
member/user/jaxb/impl/runtime/MSVValidator.java
member/user/jaxb/ObjectFactory.java
member/user/jaxb/Userinfo.java
member/user/jaxb/UserinfoType.java
member/user/jaxb/jaxb.properties
member/user/jaxb/bgm.ser

xjc.bat, xjc.sh 는 JAXB/bin 디렉토리에 있습니다. xjc 의 보다 자세한 사용 법은 –help 옵션으로 보실 수 있습니다.
PS : bgm.ser 파일은 마샤링과 언마샤링 시기에 xml 검증을 위해서 필요한 파일입니다. 클래스 페스에 꼭 포함되어 있어야 합니다.

3. 서버 프로그램 작성
서버 프로그램은 Servlet으로 작성합니다.
package member.user.jaxb;
import java.io.ByteArrayInputStream;
import java.io.CharArrayWriter;
import javax.servlet.*;
import javax.servlet.http.*;
import java.io.PrintWriter;
import java.io.IOException;
import javax.xml.bind.JAXBContext;
import javax.xml.bind.Marshaller;
import javax.xml.bind.Unmarshaller;
public class userSVR extends HttpServlet {
private static final String CONTENT_TYPE = "text/html; charset=EUC-KR";
private String name = "";
private int age = 0;
private int Phone = 0;
private String level = "Administrator";
public void init(ServletConfig config)
throws ServletException {
super.init(config);
}
public void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
doProcess(request, response);
}
public void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
doProcess(request, response);
}
public void doProcess(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
response.setContentType(CONTENT_TYPE);
PrintWriter out = response.getWriter();
String message = request.getParameter("message");
System.out.println(message);
try {
unmarshal(message);
}
catch (Exception e) {
e.printStackTrace();
}
try {
marshal(out);
}
catch (Exception e) {
e.printStackTrace();
}
out.close();
}
public void marshal(PrintWriter out)
throws Exception {
CharArrayWriter charArrayWriter = new CharArrayWriter();
ObjectFactory objFactory = new ObjectFactory();
Userinfo userinfo = objFactory.createUserinfo();
userinfo.setName(name);
userinfo.setAge(age);
userinfo.setPhone(Phone);
userinfo.setMemberLevel(level);
JAXBContext jaxbContext = JAXBContext.newInstance("member.user.jaxb");
Marshaller marshaller = jaxbContext.createMarshaller();
marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, new Boolean(true));
marshaller.marshal(userinfo, charArrayWriter);
String xmlOutput = charArrayWriter.toString();
System.out.println(" Send XML : "+xmlOutput);
out.println(xmlOutput);
}
public void unmarshal(String message) throws Exception {
ByteArrayInputStream bais =
new ByteArrayInputStream(message.getBytes());
JAXBContext jc = JAXBContext.newInstance("member.user.jaxb");
Unmarshaller unmarshaller = jc.createUnmarshaller();
unmarshaller.setValidating(true);
Userinfo instance = (Userinfo)unmarshaller.unmarshal(bais);
name = instance.getName();
age = instance.getAge();
Phone = instance.getPhone();
System.out.println("##########################################");
System.out.println("user JAXB GET DATA -->");
System.out.println("Name : "+name);
System.out.println("AGE : "+age);
System.out.println("Phone : "+Phone);
}
}

- marshal Method
Java 객체를 XML문서로 직렬화 하는 메서드 입니다.
JAXBContext jaxbContext = JAXBContext.newInstance("member.user.jaxb"); 메서드는 위에서 작성한 바인딩 클래스 패키지를 파라미터로 입력하여 JAXBContext 작성합니다.
Marshaller marshaller = jaxbContext.createMarshaller(); marshalling 담당할 Marshaller Object 생성합니다.
marshaller.marshal(userinfo, charArrayWriter); userinfo 인스턴스를 Marshalling 합니다.
- unmarshal Method
Unmarshaller unmarshaller = jc.createUnmarshaller(); unmarshalliing 담당한 Unmarshaller Object 생성합니다.
unmarshaller.setValidating(true); setValidating() true 설정되어 있다면 JAXB 런타임 API 인스턴스 데이터를 가진 XML JAXB 런타임 API XML 스키마에 의해 정의된 제약에 맞는지 검사합니다.
Userinfo instance = (Userinfo)unmarshaller.unmarshal(bais); XML userinfo 인스턴스로 직렬화 합니다.

4. 서버 프로그램 배포
배포를 위해 web.xml 파일에 위에서 작성한 Servlet을 매핑 합니다.
web.xml
<?xml version = '1.0' encoding = 'EUC-KR'?>
<!DOCTYPE web-app PUBLIC "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN" "http://java.sun.com/dtd/web-app_2_3.dtd">
<web-app>
<description>Empty web.xml file for Web Application</description>
<servlet>
<servlet-name>userSVR</servlet-name>
<servlet-class>member.user.jaxb.userSVR</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>userSVR</servlet-name>
<url-pattern>/usersvr</url-pattern>
</servlet-mapping>
<session-config>
<session-timeout>35</session-timeout>
</session-config>
<mime-mapping>
<extension>html</extension>
<mime-type>text/html</mime-type>
</mime-mapping>
<mime-mapping>
<extension>txt</extension>
<mime-type>text/plain</mime-type>
</mime-mapping>
</web-app>

Tomcat 5.0 for JWSDP 1.4에 “jaxbtest” context를 만들어 배포합니다. 위에서 XML 스키마로부터 축출하여 컴파일 한 클래스는 WEB-INF/classes에 위치 시킵니다.

5. 클라이언트 프로그램 작성
import java.io.BufferedReader;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.URL;
import java.net.URLConnection;
import java.net.URLEncoder;
public class jaxbClient {
public jaxbClient() throws Exception {
StringBuffer buffer = new StringBuffer();
buffer.append("<?xml version="1.0" encoding="UTF-8" standalone="yes"?> n");
buffer.append("<userinfo> n");
buffer.append("<name>inter999</name> n");
buffer.append("<age>32</age> n");
buffer.append("<phone>5298989</phone> n");
buffer.append("<memberLevel></memberLevel> n");
buffer.append("</userinfo>");
URL url =
new URL("http","192.168.11.128",
8080,
"/jaxbtest/usersvr?message="+URLEncoder.encode(buffer.toString()));
URLConnection urlcon = url.openConnection();
InputStream in = urlcon.getInputStream();
BufferedReader inre = new BufferedReader(new InputStreamReader(in));
String message = "";
while((message = inre.readLine()) != null)
System.out.println(message);
}
public static void main(String args[]) throws Exception {
jaxbClient client = new jaxbClient();
}
}

6. 실행
클라이언트 실행 화면
[craftlee@hurukku JAXB]$ java jaxbClient
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<userinfo>
<name>inter999</name>
<age>32</age>
<phone>5298989</phone>
<memberLevel>Administrator</memberLevel>
</userinfo>

서버측 로그
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<userinfo>
<name>inter999</name>
<age>32</age>
<phone>5298989</phone>
<memberLevel></memberLevel>
</userinfo>
##########################################
user JAXB GET DATA -->
Name : inter999
AGE : 32
Phone : 5298989
Send XML : <?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<userinfo>
<name>inter999</name>
<age>32</age>
<phone>5298989</phone>
<memberLevel>Administrator</memberLevel>
</userinfo>

댓글 없음:

댓글 쓰기

블록체인 개요 및 오픈소스 동향

블록체인(block chain) 블록체인은 공공 거래장부이며 가상 화폐로 거래할때 발생할때 발생할 수 있는 해킹을 막는 기술. 분산 데이터베이스의 한 형태로, 지속적으로 성장하는 데이터 기록 리스트로서 분산 노드의 운영자에 의한 임의 조작이 불가...