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 리포지토리 에서 다운로드할 수 있습니다 .