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; } }