From this output, we can clearly see that the containing tag uses the fully-qualified class name of Customer by default.

There are many reasons we might decide that the default behavior doesn’t suit our needs. For example, we might not be comfortable exposing the package structure of our application. Also, the XML generated is significantly longer.

5. Aliases

An alias is a name we wish to use for elements rather than using default names.

For example, we can replace com.baeldung.pojo.Customer with customer by registering an alias for the Customer class. We can also add aliases for properties of a class. By using aliases, we can make our XML output much more readable and less Java-specific.

5.1. Class Aliases

Aliases can be registered either programmatically or using annotations.

Let’s now annotate our Customer class with @XStreamAlias:

@XStreamAlias("customer")

Now we need to configure our instance to use this annotation:

xstream.processAnnotations(Customer.class);

Alternatively, if we wish to configure an alias programmatically, we can use the code below:

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

Whether using the alias or programmatic configuration, the output for a Customer object will be much cleaner:

5.2. Field Aliases

We can also add aliases for fields using the same annotation used for aliasing classes. For example, if we wanted the field firstName to be replaced with fn in the XML representation, we could use the following annotation:

@XStreamAlias("fn")
private String firstName;

Alternatively, we can accomplish the same goal programmatically:

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

The aliasField method accepts three arguments: the alias we wish to use, the class in which the property is defined, and the property name we wish to alias.

7.3. Converter Priority

The converters can be registered with an explicit priority. By default they are registered with XStream.PRIORITY_NORMAL. Converters of same priority will be used in the reverse sequence they have been registered. The default converter, i.e. the converter which will be used if no other registered converter is suitable, can be registered with priority XStream.PRIORITY_VERY_LOW. XStream uses by default the ReflectionConverter as the fallback converter.

8.Omitting Fields

We can omit fields from our generated XML using either annotations or programmatic configuration. In order to omit a field using an annotation, we simply apply the @XStreamOmitField annotation to the field in question:

@XStreamOmitField
private String firstName;

In order to omit the field programmatically, we use the following method:

xstream.omitField(Customer.class, "firstName");

Whichever method we select, the output is the same:

<customer>
<lastName>Doe</lastName>
<dob>14-02-1986</dob>
</customer>

9. Attribute Fields

Sometimes we may wish to serialize a field as an attribute of an element rather than as element itself. Suppose we add a contactType field:

private String contactType;

If we want to set contactType as an XML attribute, we can use the @XStreamAsAttribute annotation:

10. Concurrency

XStream’s processing model presents some challenges. Once theinstance is configured, it is thread-safe.

It is important to note that processing of annotations modifies the configuration just before marshalling/unmarshalling. And so – if we require the instance to be configured on-the-fly using annotations, it is generally a good idea to use a separate XStream instance for each thread.

11. Conclusion

In this article, we covered the basics of using XStream to convert objects to XML. We also learned about customizations we can use to ensure the XML output meets our needs. Finally, we looked at thread-safety problems with annotations.

In the next article in this series, we will learn about converting XML back to Java objects.

The complete source code for this article can be downloaded from the linked GitHub repository.

Generic bottom

I just announced the new Learn Spring course, focused on the fundamentals of Spring 5 and Spring Boot 2: