Jackson으로 XML을 파싱하기 위해서 다음의 dependency를 추가합니다. Jackson이 이미 dependency로 추가되어 있다면 버전 충돌이 발생하지 않도록 버전을 맞추시기 바랍니다.

<dependency>
    <groupId>com.fasterxml.jackson.dataformat</groupId>
    <artifactId>jackson-dataformat-xml</artifactId>
    <version>2.11.2</version>
</dependency>

XML이 있는 경우 다음과 같이 XmlMapper로 파싱할 수 있습니다. 만약에 unmarshal할 Type을 모르겠다면 Map으로 하시기 바랍니다. 물론 Map에서 값을 꺼내기 위해서 코드를 많이 작성해야 합니다. Map의 경우 Key Value 형식으로 데이터가 저장되므로 배열을 넣는 경우 문제가 발생할 수 있으므로 POJO(Plain Old Java Object)로 매핑하는 것을 권장합니다.

String xml = "<user><name>BYOUNG GON, KIM</name><username>fharenheit</username></user>";
XmlMapper mapper = new XmlMapper();
User user = mapper.readValue(xml, User.class);

다음은 unmarshal에 사용한 xml 파일입니다. 특이한 구조를 하고 있습니다.

<AccessControlPolicy xmlns="http://s3.amazonaws.com/doc/2006-03-01/">
    <Owner>
        <ID>852b113e7a2f25102679df27bb0ae12b3f85be6BucketOwnerCanonicalUserID</ID>
        <DisplayName>OwnerDisplayName</DisplayName>
    </Owner>
    <AccessControlList>
        <Grant>
            <Grantee xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
                     xsi:type="CanonicalUser">
                <ID>852b113e7a2f25102679df27bb0ae12b3f85be6BucketOwnerCanonicalUserID</ID>
                <DisplayName>OwnerDisplayName</DisplayName>
            </Grantee>
            <Permission>FULL_CONTROL</Permission>
        </Grant>
        <Grant>
            <Grantee xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="Group">
                <URI>http://acs.amazonaws.com/groups/global/AllUsers</URI>
            </Grantee>
            <Permission>READ</Permission>
        </Grant>
        <Grant>
            <Grantee xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="Group">
                <URI>http://acs.amazonaws.com/groups/s3/LogDelivery</URI>
            </Grantee>
            <Permission>WRITE</Permission>
        </Grant>
        <Grant>
            <Grantee xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="AmazonCustomerByEmail">
                <EmailAddress>xyz@amazon.com</EmailAddress>
            </Grantee>
            <Permission>WRITE_ACP</Permission>
        </Grant>
        <Grant>
            <Grantee xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="CanonicalUser">
                <ID>f30716ab7115dcb44a5ef76e9d74b8e20567f63TestAccountCanonicalUserID</ID>
            </Grantee>
            <Permission>READ_ACP</Permission>
        </Grant>
        <Grant>
            <Grantee xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="CanonicalUser">
                <ID>75aa57f09aa0c8caeab4f8c24e99d10f8e7faeeExampleCanonicalUserID</ID>
                <DisplayName>CustomerName@amazon.com</DisplayName>
            </Grantee>
            <Permission>FULL_CONTROL</Permission>
        </Grant>
    </AccessControlList>
</AccessControlPolicy>

Jackson에서 제공하는 Annotation을 통해서 namespace를 매핑합니다.

import com.fasterxml.jackson.dataformat.xml.annotation.JacksonXmlProperty;
import com.fasterxml.jackson.dataformat.xml.annotation.JacksonXmlRootElement;

@JacksonXmlRootElement(namespace = "http://s3.amazonaws.com/doc/2006-03-01/")    → ROOT 노드인 경우 사용하도록 함
public class AccessControlPolicy {

    @JacksonXmlProperty(localName = "Owner")       → XML에서는 <Owner>이지만 Java에서는 owner이므로 명시적으로 name을 정의함
    protected Owner owner;

    @JacksonXmlProperty(localName = "AccessControlList")
    protected AccessControlList accessControlList;

    public Owner getOwner() {
        return owner;
    }

    public void setOwner(Owner value) {
        this.owner = value;
    }

    public AccessControlList getAccessControlList() {
        return accessControlList;
    }

    public void setAccessControlList(AccessControlList value) {
        this.accessControlList = value;
    }

}

@JacksonXmlElementWrapper 은 List 형을 정의할 때 사용할 수 있습니다.

import com.fasterxml.jackson.dataformat.xml.annotation.JacksonXmlElementWrapper;
import com.fasterxml.jackson.dataformat.xml.annotation.JacksonXmlProperty;

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

public class AccessControlList {

    @JacksonXmlElementWrapper(useWrapping = false)                → List형인 경우 지정하도록 함
    @JacksonXmlProperty(localName = "Grant")
    protected List<Grant> grant;

    public List<Grant> getGrant() {
        if (grant == null) {
            grant = new ArrayList<Grant>();
        }
        return this.grant;
    }

}