Jettison site: http://jettison.codehaus.org/
XStream과 Jettison 모두 codehaus 의 오픈소스다.
결론적으로 말하면 XStream에서 JSON처리를 위해 Jettison을 사용한다.
우선 두 오픈소스 프로젝트에 대해서 간략히 살펴보자.
XStream
XStream is a simple library to serialize objects to XML and back again.
XStream 사이트에 소개된 말이다. 간단히 말하면 Java Object와 XML을 상호변환하기 위한 심플한 라이브러리란다. Java Object와 XML 변환은 XStream 말고도 자바 표준 API인 JAX-B나 Bea에서 아파치에 기증한 XMLBeans등이 있지만 XStream도 그런 기능을 한단다. 하지만 심플하다고 소개한다. JAXB가 매핑을 하기 위해서 (annotation을 사용한다고 해도) 이래저래 좀 복잡하기는 하다.
Features를 살펴보면 좀 더 자세히 알 수 있다. 오해의 소지를 줄이기 위해서 원문을 그대로 옮겨 적는다.
Features
- Ease of use. A high level facade is supplied that simplifies common use cases.
- No mappings required. Most objects can be serialized without need for specifying mappings.
- Performance. Speed and low memory footprint are a crucial part of the design, making it suitable for large object graphs or systems with high message throughput.
- Clean XML. No information is duplicated that can be obtained via reflection. This results in XML that is easier to read for humans and more compact than native Java serialization.
- Requires no modifications to objects. Serializes internal fields, including private and final. Supports non-public and inner classes. Classes are not required to have default constructor.
- Full object graph support. Duplicate references encountered in the object-model will be maintained. Supports circular references.
- Integrates with other XML APIs. By implementing an interface, XStream can serialize directly to/from any tree structure (not just XML).
- Customizable conversion strategies. Strategies can be registered allowing customization of how particular types are represented as XML.
- Error messages. When an exception occurs due to malformed XML, detailed diagnostics are provided to help isolate and fix the problem.
- Alternative output format. The modular design allows other output formats. XStream ships currently with JSON support and morphing.
간단히 한글로 옮겨 보겠다.
- 사용 편이성 : 일반적인 유즈케이스를 단순화시킨 고수준의 facade를 제공한다.
- mapping 설정이 필요없다 : 대부분의 객체들은 별도의 매핑이 없이도 serialize할 수 있다.
- 성능: 처리속도가 빠르고 적은 메모리 사용은 XStream 설계의 핵심 부분이다. 이것은 복잡한 객체 구조도 빠르게 처리할 수 있다. 이부분은 처리속도는 아주 빠르지만, CPU와 메모리 사용량이 많은 XMLBeans와 비교하면 눈에 띄는 장점으로 판단된다.
- 깨끗한 XML: 중복되는 정보도 없고, 사람이 읽기도 용이하고 Java serialization보다도 간결한다.
- 객체를 수정할 필요가 없다: 내부 필드를 serializable하게 변경할 필요도 없고, private이나 final로 변환할 필요도 없다. non-public inner class들도 지원하며 심지어는 디폴트 생성자도 필요 없다.
- 복잡한 객체 구조도 완벽하게 지원한다: Object graph는 객체가 하위 객체를 포함하는 관계를 나타내는 말이므로 객체 구조라고 표현하겠다. 중복 참조도 지원한다. 순환참조도 지원한다.
- 타 XML API와 통합할 수 있다.
- 변환 전략을 커스터마이즈 할 수 있다.
- 에러 메시지: 적절하지 않은 XML로 인해 에러가 발생할 경우 문제를 해결할 수 있는 상세한 에러 메시지가 제공된다.
- 타 포맷으로 출력할 수 있다: XStream은 현재 JSON과 morphings를 처리할 수 있다.
나는 가장 마지막 특징인 JSON 처리를 위해 XStream에 관심을 갖고 있다. 처리 방식이 StAX인것도 호감이 간다.
XStream은 변환(Transport), 저장(Persistence), 환경설정(Configuration), 단위테스트(Unit Tests)등의 용도로 사용한다.
Jettison
A JSON StAX Implementaion. JSON처리용 StAX 구현라이브러리 쯤으로 해석하면 될 것 같다.
Jettison은 StAX와 DOM이 XML을 읽고 쓰는 것처럼 JSON을 읽고 쓸 수 있는 Java API모음이다.
Jettison은 CXF와 같은 웹서비스 프레임웍에서 JSON 기반의 웹서비스를 가능하게 하고, XStream과 같은 XML serialization 프레임웍에서 JSON변환을 가능하게 한다.
프로젝트 소개는 이정도로 마무리 할까 한다.
xstream을 다운 받으면 jettison 라이브러리가 함께 포함되어 있다.
xstream에 포함되어 있는 jar파일들을 클래스패스에 추가하고 아래의 소스코드를 실행해 보면 사용법은 그리 어렵지 않다.
java object 객체
package xstream.sample;
import java.util.List;
public class PurchaseOrder {
Customer customer;
List<Product> items = null;
ShippingInfo shippingInfo;
public Customer getCustomer() {
return customer;
}
public void setCustomer(Customer customer) {
this.customer = customer;
}
public List<Product> getItems() {
return items;
}
public void setItems(List<Product> items) {
this.items = items;
}
public ShippingInfo getShippingInfo() {
return shippingInfo;
}
public void setShippingInfo(ShippingInfo shippingInfo) {
this.shippingInfo = shippingInfo;
}
}
package xstream.sample;
public class Customer {
String customerId;
String email;
public String getCustomerId() {
return customerId;
}
public void setCustomerId(String customerId) {
this.customerId = customerId;
}
public String getEmail() {
return email;
}
public void setEmail(String email) {
this.email = email;
}
}
package xstream.sample;
public class Product{
private String productId;
private double price;
public String getProductId() {
return productId;
}
public void setProductId(String productId) {
this.productId = productId;
}
public double getPrice() {
return price;
}
public void setPrice(double price) {
this.price = price;
}
}
package xstream.sample;
public class ShippingInfo {
String address;
public String getAddress() {
return address;
}
public void setAddress(String address) {
this.address = address;
}
}
실행 코드
package xstream.sample;
import java.util.ArrayList;
import org.junit.Test;
import com.thoughtworks.xstream.XStream;
import com.thoughtworks.xstream.io.json.JettisonMappedXmlDriver;
public class XstreamSample {
@Test
public void testXStream() throws Exception {
PurchaseOrder po = new PurchaseOrder();
Customer customer = new Customer();
customer.setCustomerId("cid1");
customer.setEmail("email@gmail.com");
po.setCustomer(customer);
ShippingInfo shippingInfo = new ShippingInfo();
shippingInfo.setAddress("address1");
po.setShippingInfo(shippingInfo);
ArrayList<Product> items = new ArrayList<Product>();
Product item1 = new Product();
item1.setProductId("pid1");
item1.setPrice(100);
items.add(item1);
Product item2 = new Product();
item2.setProductId("pid2");
item2.setPrice(200);
items.add(item2);
po.setItems(items);
XStream xstream4XML = new XStream();
xstream4XML.alias("purchaseOrder", PurchaseOrder.class);
xstream4XML.alias("customer", Customer.class);
xstream4XML.alias("product", Product.class);
xstream4XML.alias("shipping", ShippingInfo.class);
System.out.println("XML RESULT");
System.out.println(xstream4XML.toXML(po));
XStream xstream4JSON = new XStream(new JettisonMappedXmlDriver());
xstream4JSON.alias("purchaseOrder", PurchaseOrder.class);
xstream4JSON.alias("customer", Customer.class);
xstream4JSON.alias("product", Product.class);
xstream4JSON.alias("shipping", ShippingInfo.class);
System.out.println();
System.out.println("JSON RESULT");
System.out.println(xstream4JSON.toXML(po));
}
}
콘솔화면 출력
XML RESULT
<purchaseOrder>
<customer>
<customerId>cid1</customerId>
<email>email@gmail.com</email>
</customer>
<items>
<product>
<productId>pid1</productId>
<price>100.0</price>
</product>
<product>
<productId>pid2</productId>
<price>200.0</price>
</product>
</items>
<shippingInfo>
<address>address1</address>
</shippingInfo>
</purchaseOrder>
JSON RESULT
{"purchaseOrder":{"customer":{"customerId":"cid1","email":"email@gmail.com"},"items":{"product":[{"productId":"pid1","price":100},{"productId":"pid2","price":200}]},"shippingInfo":{"address":"address1"}}}
사용하기 편하고 간단하며 깨끗한 XML이 출력되고 JSON도 지원되는 것 같다. ^^;;