1. 개요

이전 기사 에서 XStream을 사용하여 Java 객체를 XML로 직렬화하는 방법을 배웠습니다. 이 예제에서는 역순으로 XML을 Java 객체로 역직렬화하는 방법을 배웁니다. 이러한 작업은 어노테이션을 사용하거나 프로그래밍 방식으로 수행할 수 있습니다.

XStream 및 해당 의존성을 설정하기 위한 기본 요구 사항에 대해 알아보려면 이전 기사를 참조하십시오.

2. XML에서 개체 역직렬화

우선 다음 XML이 있다고 가정합니다.

<com.baeldung.pojo.Customer>
    <firstName>John</firstName>
    <lastName>Doe</lastName>
    <dob>1986-02-14 03:46:16.381 UTC</dob>
</com.baeldung.pojo.Customer>

이것을 Java Customer 개체로 변환해야 합니다.

public class Customer {
 
    private String firstName;
    private String lastName;
    private Date dob;
 
    // standard setters and getters
}

XML은 File , InputStream , Reader 또는 String 등 다양한 방법으로 입력할 수 있습니다 . 간단히 하기 위해 String 개체 에 위의 XML이 있다고 가정 합니다.

Customer convertedCustomer = (Customer) xstream.fromXML(customerXmlString);
Assert.assertTrue(convertedCustomer.getFirstName().equals("John"));

3. Security 측면

XStream은 문서화되지 않은 Java 기능과 Java Reflection을 사용하기 때문에 임의 코드 실행 또는 원격 명령 실행 공격에 취약할 수 있습니다.

심층적인 Security 고려 사항은 이 사용방법(예제)의 범위를 벗어나지만 위협을 설명 하는 전용 문서 가 있습니다. 또한 XStream의 공식 페이지 를 확인하는 것도 좋습니다.

사용방법(예제)의 목적을 위해 모든 클래스가 "안전"하다고 가정합니다. 따라서 XStream을 구성해야 합니다.

XStream xstream = new XStream();
xstream.allowTypesByWildcard(new String[]{"com.baeldung.**"});

4. 별칭

첫 번째 예에서 XML은 Customer 클래스 의 위치와 일치하는 가장 바깥쪽 XML 태그에 클래스의 정규화된 이름을 가졌습니다 . 이 설정을 통해 XStream은 추가 구성 없이 XML을 객체로 쉽게 변환합니다. 그러나 우리는 항상 이러한 조건을 가지고 있지 않을 수 있습니다. XML 태그 이름 지정을 제어할 수 없거나 필드에 대한 별칭을 추가하기로 결정할 수 있습니다.

예를 들어 외부 태그에 정규화된 클래스 이름을 사용하지 않도록 XML을 수정했다고 가정합니다.

<customer>
    <firstName>John</firstName>
    <lastName>Doe</lastName>
    <dob>1986-02-14 03:46:16.381 UTC</dob>
</customer>

별칭을 생성하여 이 XML을 가릴 수 있습니다.

4.1. 클래스 별칭

프로그래밍 방식으로 또는 어노테이션을 사용하여 XStream 인스턴스에 별칭을 등록합니다. @XStreamAlias 로 Customer 클래스에 어노테이션을 달 수 있습니다 .

@XStreamAlias("customer")
public class Customer {
    //...
}

이제 이 어노테이션을 사용하도록 XStream 인스턴스를 구성해야 합니다.

xstream.processAnnotations(Customer.class);

또는 프로그래밍 방식으로 별칭을 구성하려는 경우 아래 코드를 사용할 수 있습니다.

xstream.alias("customer", Customer.class);

4.2. 필드 별칭

다음 XML이 있다고 가정합니다.

<customer>
    <fn>John</fn>
    <lastName>Doe</lastName>
    <dob>1986-02-14 03:46:16.381 UTC</dob>
</customer>

fn 태그 는 Customer 개체 의 필드와 일치하지 않으므로 역직렬화하려면 해당 필드에 대한 별칭을 정의해야 합니다. 다음 어노테이션을 사용하여 이를 달성할 수 있습니다.

@XStreamAlias("fn")
private String firstName;

또는 프로그래밍 방식으로 동일한 목표를 달성할 수 있습니다.

xstream.aliasField("fn", Customer.class, "firstName");

5. 암시적 컬렉션

간단한 ContactDetails List을 포함하는 다음 XML이 있다고 가정해 보겠습니다 .

<customer>
    <firstName>John</firstName>
    <lastName>Doe</lastName>
    <dob>1986-02-14 04:14:20.541 UTC</dob>
    <ContactDetails>
        <mobile>6673543265</mobile>
        <landline>0124-2460311</landline>
    </ContactDetails>
    <ContactDetails>...</ContactDetails>
</customer>

Java 개체 의 List<ContactDetails> 필드에 ContactDetails List을 로드하려고 합니다. 다음 어노테이션을 사용하여 이를 달성할 수 있습니다.

@XStreamImplicit
private List<ContactDetails> contactDetailsList;

또는 프로그래밍 방식으로 동일한 목표를 달성할 수 있습니다.

xstream.addImplicitCollection(Customer.class, "contactDetailsList");

6. 필드 무시

다음 XML이 있다고 가정해 보겠습니다.

<customer>
    <firstName>John</firstName>
    <lastName>Doe</lastName>
    <dob>1986-02-14 04:14:20.541 UTC</dob>
    <fullName>John Doe</fullName>
</customer>

위의 XML에는 Java 고객 개체 에서 누락된 추가 요소 <fullName> 이 있습니다.

추가 요소를 고려하지 않고 위의 xml을 역직렬화하려고 하면 프로그램에서 UnknownFieldException 이 발생 합니다.

No such field com.baeldung.pojo.Customer.fullName

예외에 분명히 나와 있듯이 XStream은 fullName 필드를 인식하지 못합니다 .

이 문제를 극복하려면 알 수 없는 요소를 무시하도록 구성해야 합니다.

xstream.ignoreUnknownElements();

7. 속성 필드

개체의 필드로 역직렬화하려는 요소의 일부로 속성이 있는 XML이 있다고 가정합니다. ContactDetails 개체 에 contactType 특성을 추가 합니다.

<ContactDetails contactType="Office">
    <mobile>6673543265</mobile>
    <landline>0124-2460311</landline>
</ContactDetails>

contactType XML 속성 을 역직렬화하려면 표시하려는 필드에 @XStreamAsAttribute 어노테이션을 사용할 수 있습니다.

@XStreamAsAttribute
private String contactType;

또는 프로그래밍 방식으로 동일한 목표를 달성할 수 있습니다.

xstream.useAttributeFor(ContactDetails.class, "contactType");

8. 결론

이 기사에서는 XStream을 사용하여 XML을 Java 객체로 역직렬화할 때 사용할 수 있는 옵션을 탐색했습니다.

이 기사의 전체 소스 코드는 연결된 GitHub 리포지토리 에서 다운로드할 수 있습니다 .

Generic footer banner