[번역] XStream 배우기 : 별칭(Alias) 배우기

이글은 XStream 교재 중 "Alias Tutorial"을 번역한 것입니다.

문제

고객이 이미 정의된 기본 XML을 가지고 있어서 XStream으로 이것을 읽고 써야 한다고 가정해봅니다.
<blog author="Guilherme Silveira">
<entry>
<title>first</title>
<description>My first blog entry.</description>
</entry>
<entry>
<title>tutorial</title>
<description>
Today we have developed a nice alias tutorial. Tell your friends! NOW!
</description>
</entry>
</blog>
  1. 2분만에 배우기
  2. 별칭(Alias) 배우기
  3. 애노테이션(Annotations) 배우기
  4. 변환기(Converter) 배우기
  5. 객체 스트림(Object Streams) 배우기
  6. 영속화 API(Persistence API) 배우기
  7. JSON 배우기
위의 XML에 기반해서 모델 클래스 몇개를 만들고 이 포멧을 읽고 쓰도록 XStream을 설정할 것입니다.

모델 객체

XML 파일을 표현할 클래스들은 다음과 같습니다. 가장 먼저 간단한 Blog 객체부터 시작해 보겠습니다. 

First things first, the classes which shall represent our xml files are shown next, beginning with a simple Blog:

package com.thoughtworks.xstream;

public class Blog {
private Author author;
private List entries = new ArrayList();

public Blog(Author author) {
this.author = author;
}

public void add(Entry entry) {
entries.add(entry);
}

public List getContent() {
return entries;
}
}

이름을 갖는 저작자 객체는 이렇습니다.

package com.thoughtworks.xstream;

public class Author {
private String name;
public Author(String name) {
this.name = name;
}
public String getName() {
return name;
}
}

블로그에 등록된 글은 타이틀과 설명을 담고 있습니다.

package com.thoughtworks.xstream;

public class Entry {
private String title, description;
public Entry(String title, String description) {
this.title = title;
this.description = description;
}
}

여기서는 getter와 setter를 만들지 않았지만 코드를 이해하기 좋게 하고 싶다거나 그것들을 있었으면 좋겠다고 생각하면 임의로 만들어도 된다.

간단 테스트

간단히 blog 객체를 생성해서 xstream을 사용해 볼 수 있습니다.
public static void main(String[] args) {

Blog teamBlog = new Blog(new Author("Guilherme Silveira"));
teamBlog.add(new Entry("first","My first blog entry."));
teamBlog.add(new Entry("tutorial",
"Today we have developed a nice alias tutorial. Tell your friends! NOW!"));

XStream xstream = new XStream();
System.out.println(xstream.toXML(teamBlog));

}

하지만 결과는 우리가 원하는 것처럼 깔끔하지 않네요.

<com.thoughtworks.xstream.Blog>
<author>
<name>Guilherme Silveira</name>
</author>
<entries>
<com.thoughtworks.xstream.Entry>
<title>first</title>
<description>My first blog entry.</description>
</com.thoughtworks.xstream.Entry>
<com.thoughtworks.xstream.Entry>
<title>tutorial</title>
<description>
Today we have developed a nice alias tutorial. Tell your friends! NOW!
</description>
</com.thoughtworks.xstream.Entry>
</entries>
</com.thoughtworks.xstream.Blog>


객체 별칭

먼저 할 일은 XStream이 com.thoughtworks.xstream.Blog 클래스를 지칭하는 법을 바꾸는 일입니다. 'blog'를 그 클래스를 가리키는 명칭이라고 하고 blog라는 클래스의 별칭을 만들겠습니다.
xstream.alias("blog", Blog.class);

같은 식으로 Entry 클래스의 별칭도 entry라고 하죠.

xstream.alias("entry", Entry.class);

이제 출력 결과는 이렇게 됩니다.

<blog>
<author>
<name>Guilherme Silveira</name>
</author>
<entries>
<entry>
<title>first</title>
<description>My first blog entry.</description>
</entry>
<entry>
<title>tutorial</title>
<description>
Today we have developed a nice alias tutorial. Tell your friends! NOW!
</description>
</entry>
</entries>
</blog>


entries 테그 빼기

이제 내재적 컬렉션(implicit collection)이라고 부르는 것을 구현해보겠습니다. 루트 테그를 표시할 필요가 없는 컬렉션을 가지고 있다면  내재적 컬렉션으로 대응시킬 수 있습니다.

우리의 경우는 entries 테그를 표시하지 않고 단순히 entry 테그들을 연달아 보여주고 싶습니다.

addImplicitCollection 메소드를 간단히 호출하는 것으로 위에 설명한 것 처럼 우리가 entries 테그를 출력하기 원지 않는 다는 것을XStream이 알게 할 수 있습니다.

package com.thoughtworks.xstream;

import java.util.ArrayList;
import java.util.List;

public class Test {

public static void main(String[] args) {

Blog teamBlog = new Blog(new Author("Guilherme Silveira"));
teamBlog.add(new Entry("first","My first blog entry."));
teamBlog.add(new Entry("tutorial",
"Today we have developed a nice alias tutorial. Tell your friends! NOW!"));

XStream xstream = new XStream();
xstream.alias("blog", Blog.class);
xstream.alias("entry", Entry.class);

xstream.addImplicitCollection(Blog.class, "entries");

System.out.println(xstream.toXML(teamBlog));

}
}

addImplicitCollection 메소드 호출 부분을 주목해서 보십시오. 어떤 클레스와 어떤 멤버 변수가 우리가 원하는 데로 행동할지 알려주고 있습니다.

결과는 우리가 원하는 것과 아주 흡사합니다.

<blog>
<author>
<name>Guilherme Silveira</name>
</author>
<entry>
<title>first</title>
<description>My first blog entry.</description>
</entry>
<entry>
<title>tutorial</title>
<description>
Today we have developed a nice alias tutorial. Tell your friends! NOW!
</description>
</entry>
</blog>


속성 별칭

다음 단계는 author 멤버 변수를 XML 속성이 되게 하는 것 입니다. 이를 위해서는 Blog 클래스의 author 필드를 "author" 속성이 되도록 XStream에게 알려줘야 합니다.
                xstream.useAttributeFor(Blog.class, "author");

이제 한가지 문제만 남았습니다. 어떻게 하면 XStream이 Author 객체를 문자열로 변환해서 xml 테그 속성으로 쓰도록 할 수 있을까요?

SimpeValueConver를 구현해서 Author 변환기를 만들어 보겠습니다.
class AuthorConverter implements SingleValueConverter {
}

먼저 XStream에게 처리 할 타입이 뭔지 알려주는 메소드를 구현하겠습니다.


The first method to implement tells XStream which types it can deal with:

        public boolean canConvert(Class type) {
return type.equals(Author.class);
}

다음은 Author 객체에서 문자열을 추출하는데 사용될 메소드입니다.

        public String toString(Object obj) {
return ((Author) obj).getName();
}

세번째는 반대로 String를 주면 Author 객체를 반환하는 메소드입니다.

        public Object fromString(String name) {
return new Author(name);
}

결국 문자열을 객체(여기서는 Author)로 변환하는 일을 담당 할 단일 값 변환기의 전체 모습은 다음과 같습니다.

class AuthorConverter implements SingleValueConverter {

public String toString(Object obj) {
return ((Author) obj).getName();
}

public Object fromString(String name) {
return new Author(name);
}

public boolean canConvert(Class type) {
return type.equals(Author.class);
}

}

이 변환기를 등록해보겠습니다.

public class Test {

public static void main(String[] args) {

Blog teamBlog = new Blog(new Author("Guilherme Silveira"));
teamBlog.add(new Entry("first","My first blog entry."));
teamBlog.add(new Entry("tutorial",
"Today we have developed a nice alias tutorial. Tell your friends! NOW!"));

XStream xstream = new XStream();
xstream.alias("blog", Blog.class);
xstream.alias("entry", Entry.class);

xstream.addImplicitCollection(Blog.class, "entries");

xstream.useAttributeFor(Blog.class, "author");
xstream.registerConverter(new AuthorConverter());

System.out.println(xstream.toXML(teamBlog));

}
}

결과는?

<blog author="Guilherme Silveira">
<entry>
<title>first</title>
<description>My first blog entry.</description>
</entry>
<entry>
<title>tutorial</title>
<description>
Today we have developed a nice alias tutorial. Tell your friends! NOW!
</description>
</entry>
</blog>

useAttributeFor 메소드와 비슷한 기능을 하는 다른 중첩 메소드가 있는데 이 메소드는 (Class, String, String) 처럼 끝 부분에 필드의 별칭인 문자열을 추가로 받습니다. 예를 들어 useAttributeFor(Blog.clas, "author", "auth")라고 하면 author 필드는 "auth"라는 속성에 대응됩니다.

(역자주 : 이 부분은 이 교제가 잘못된 것  같습니다. XStream에는 패러미터를 세 개 받는 useAttributeFor(Class, String, String) 메소드는 없습니다. 대신 aliasAttribute(Class, String,  String) 메소드가 있습니다.)



종합

별칭(alias)과 변환기(converter)를 사용하면 원하는 거의 대부분의 XML을 구성할 수 있는 충분한 능력 갖게 됩니다.

변환기에 대한 교제를 읽는 것도 잊지 마십시오. XStream을 사용하서 만들 수 있는 다른 유형의 변환기들을 볼 수 있습니다.

by 박성철 | 2008/01/16 13:52 | 프로그래밍 이야기 | 트랙백 | 덧글(0)

트랙백 주소 : http://gyumee.egloos.com/tb/1296932
☞ 내 이글루에 이 글과 관련된 글 쓰기 (트랙백 보내기) [도움말]

:         :

:

비공개 덧글

◀ 이전 페이지다음 페이지 ▶