Loading...

JAVA / / 2023. 1. 12. 10:51

JAXBContext marshal, unmarshal(마샬, 언마샬)

반응형

JAXB (자바 API)

- 언마샬링(Unmarshalling) : XML 스키마를 읽어서 자바 오브젝트로 변환

- 마샬링(Marshalling) : 자바 오브젝트를 XML 스키마로 변환

 

대부분 JSON(JavaScript Object Notation)을 많이 사용하는 추세지만 XML도 적지않게 사용하고 있다.

또한 JSON을 다룰 때 자주 사용하는 Jackson을 통해서도 XML 파싱이 가능하다.

 

이번 글에서는 단순히 JAXB API를 이용하여 자바 오브젝트를 XML 형태로 변환하거나, XML을 읽어서 자바 오브젝트로 변환하는 방법을 살펴보겠다.

 

 

1. Marshal (POJO to XML)

POJO(Plain Old Java Object)를 XML로 변환

import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlRootElement;

@XmlRootElement
public class Person {
    @XmlElement
    private String name;
    @XmlElement
    private String email;
    
    // 생성자, getter, setter 생략
}
import javax.xml.bind.JAXBContext;
import javax.xml.bind.Marshaller;

public class JaxbText {

    public void marshalTest() {
        try {
            Person person = new Person("jaxb", "jaxb@hello.com");

            // JAXBContext 생성 & marshaller 생성
            JAXBContext context = JAXBContext.newInstance(Person.class);
            Marshaller marshaller = context.createMarshaller();

            // 보기 좋게 출력해주는 옵션
            marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);

            // 표준 출력으로 결과를 보여준다.
            marshaller.marshal(person, System.out);
        } catch (Exception e) {
            // ... handle exception
        }
    }

    public static void main(String[] args) {
        new JaxbText().marshalTest();
    }
}

 

- 결과

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<person>
    <name>jaxb</name>
    <email>jaxb@hello.com</email>
</person>

 

2. Unmarshal (XML to POJO)

<?xml version="1.0" encoding="UTF-8"?>
<person>
    <name>kim jaxb</name>
    <email>jaxb@hello.com</email>
</person>
import javax.xml.bind.JAXBContext;
import javax.xml.bind.Unmarshaller;
import java.io.File;

public class JaxbText {

    public void unmarshalTest() {
        try {
            // XML 파일을 읽어온다.
            File file = new File(getClass().getResource("test.xml").getFile());
            
            // JAXBContext 생성 & unmarshaller 생성
            JAXBContext context = JAXBContext.newInstance(Person.class);
            Unmarshaller unmarshaller = context.createUnmarshaller();
            
            // XML을 Person 오브젝트로 변환한다.
            Person person = (Person) unmarshaller.unmarshal(file);
            
            System.out.println("name: " + person.getName());
            System.out.println("email: " + person.getEmail());
        } catch (Exception e) {
            // ... handle exception
        }
    }
    
    public static void main(String[] args) {
        new JaxbText().unmarshalTest();
    }
}

// 출력 결과
// name: kim jaxb
// email: jaxb@hello.com

 

POJO 클래스에 사용된 @XmlElement는 옵션으로 name필드를 입력받을 수 있다.

클래스의 멤버 필드 이름과 XML 엘리먼트의 이름이 다를 경우에는 아래와 같이 설정하여 언마샬링할 수 있다.

@XmlRootElement
public class Person {
    // XML 엘리먼트 이름으로 지정할 수 있다.
    @XmlElement(name="nickname")
    private String name;
    @XmlElement
    private String email;
    
    // 생성자, getter, setter 생략
}

 

 

 

JAXB API를 이용하면 간단하게 XML 파싱을 진행할 수 있다.

다만 JaxbContext를 초기화하고 마샬러, 언마샬러를 생성하는 부분에서 주의할 점이 있다.

스레드 안전한(thread-safe) JAXBContext의 경우는 1회 생성 후 재사용을 권장하고 있다.

생성 비용이 적지않기 때문에 마샬/언마샬을 수행될 때마다 매번 생성하는 것보다 한 번 생성하고 재사용하는 편이 좋다.

 

다만, 마샬러(Marshaller)언마샬러(Unmarshaller)의 경우 스레드 안전하지 않기 때문에 마샬/언마샬이 수행될 때마다 다시 생성하는 것을 권장한다.

다행히 이를 생성하는 비용은 크지 않다.

 

 

https://madplay.github.io/post/jaxb-marshal-unmarshal

반응형