CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/maven-org-springframework--spring-oxm

Spring Object/XML Marshalling support providing generic interfaces for converting Java objects to XML and vice versa

Overview
Eval results
Files

xstream-implementation.mddocs/

XStream Implementation

The XStream implementation provides XML marshalling and unmarshalling using the XStream library. It offers an alternative to JAXB with different configuration options, security controls, and converter-based customization.

Core Class

XStreamMarshaller

The main XStream implementation class that extends AbstractMarshaller and provides XStream-based XML processing.

public class XStreamMarshaller extends AbstractMarshaller implements BeanClassLoaderAware, InitializingBean {
    
    // Configuration Methods
    public void setSupportedClasses(Class<?>... supportedClasses);
    public void setTypePermissions(TypePermission... typePermissions);
    public void setConverters(ConverterMatcher... converters);
    public void setMarshallingStrategy(MarshallingStrategy marshallingStrategy);
    public void setMode(int mode);
    public void setAliases(Map<String, ?> aliases);
    public void setAliasesByType(Map<Class<?>, String> aliasesByType);
    public void setFieldAliases(Map<String, String> fieldAliases);
    public void setUseAttributeFor(Map<?, ?> useAttributeFor);
    public void setUseAttributeForTypes(Class<?>... useAttributeForTypes);
    public void setImplicitCollections(Map<Class<?>, String> implicitCollections);
    public void setOmittedFields(Map<Class<?>, String> omittedFields);
    public void setStreamDriver(HierarchicalStreamDriver streamDriver);
    public void setEncoding(String encoding);
    public void setClassLoader(ClassLoader classLoader);
    public void setAutodetectAnnotations(boolean autodetectAnnotations);
    public void setReflectionProvider(ReflectionProvider reflectionProvider);
    public void setMapperWrappers(Class<? extends MapperWrapper>... mapperWrappers);
    
    // Security Methods - Type permissions and supported classes provide security controls
    
    // Inherited methods
    public boolean supports(Class<?> clazz);
    public void marshal(Object graph, Result result) throws IOException, XmlMappingException;
    public Object unmarshal(Source source) throws IOException, XmlMappingException;
}

Configuration Options

Basic Configuration

import org.springframework.oxm.xstream.XStreamMarshaller;

XStreamMarshaller marshaller = new XStreamMarshaller();

// Specify supported classes for security
marshaller.setSupportedClasses(Customer.class, Order.class, Product.class);

// Initialize the marshaller
marshaller.afterPropertiesSet();

Security Configuration

XStream requires explicit security configuration to prevent deserialization vulnerabilities:

import com.thoughtworks.xstream.security.TypePermission;
import com.thoughtworks.xstream.security.WildcardTypePermission;

XStreamMarshaller marshaller = new XStreamMarshaller();

// Option 1: Use supported classes (recommended)
marshaller.setSupportedClasses(Customer.class, Order.class);

// Option 2: Use type permissions for more granular control
TypePermission[] permissions = {
    new WildcardTypePermission(new String[]{"com.example.model.**"}),
    new WildcardTypePermission(new String[]{"java.util.**"})
};
marshaller.setTypePermissions(permissions);

// Security is handled through type permissions and supported classes

marshaller.afterPropertiesSet();

Aliases and Field Mapping

Customize XML element names and structure:

import java.util.HashMap;
import java.util.Map;

XStreamMarshaller marshaller = new XStreamMarshaller();
marshaller.setSupportedClasses(Customer.class, Order.class);

// Class aliases (changes root element name)
Map<String, Class<?>> aliases = new HashMap<>();
aliases.put("customer", Customer.class);
aliases.put("order", Order.class);
marshaller.setAliases(aliases);

// Type-based aliases
Map<Class<?>, String> aliasesByType = new HashMap<>();
aliasesByType.put(Customer.class, "customer");
marshaller.setAliasesByType(aliasesByType);

// Field aliases (changes property names)
Map<String, String> fieldAliases = new HashMap<>();
fieldAliases.put("Customer.firstName", "fname");
fieldAliases.put("Customer.lastName", "lname");
marshaller.setFieldAliases(fieldAliases);

marshaller.afterPropertiesSet();

Attribute Mapping

Configure which fields should be XML attributes instead of elements:

Map<String, Class<?>> useAttributeFor = new HashMap<>();
useAttributeFor.put("Customer.id", String.class);
useAttributeFor.put("Order.status", String.class);
marshaller.setUseAttributeFor(useAttributeFor);

// Or specify by type
marshaller.setUseAttributeForTypes(Long.class, Integer.class);

Collection Handling

Configure implicit collections to avoid wrapper elements:

Map<Class<?>, String> implicitCollections = new HashMap<>();
implicitCollections.put(Order.class, "items");
implicitCollections.put(Customer.class, "addresses");
marshaller.setImplicitCollections(implicitCollections);

Custom Converters

Implement custom conversion logic for specific types:

import com.thoughtworks.xstream.converters.Converter;
import com.thoughtworks.xstream.converters.MarshallingContext;
import com.thoughtworks.xstream.converters.UnmarshallingContext;
import com.thoughtworks.xstream.io.HierarchicalStreamReader;
import com.thoughtworks.xstream.io.HierarchicalStreamWriter;

public class DateConverter implements Converter {
    private SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd");
    
    @Override
    public boolean canConvert(Class type) {
        return Date.class.isAssignableFrom(type);
    }
    
    @Override
    public void marshal(Object source, HierarchicalStreamWriter writer, 
                       MarshallingContext context) {
        Date date = (Date) source;
        writer.setValue(dateFormat.format(date));
    }
    
    @Override
    public Object unmarshal(HierarchicalStreamReader reader, 
                           UnmarshallingContext context) {
        try {
            return dateFormat.parse(reader.getValue());
        } catch (ParseException e) {
            throw new ConversionException("Cannot parse date", e);
        }
    }
}

// Configure marshaller with custom converter
XStreamMarshaller marshaller = new XStreamMarshaller();
marshaller.setSupportedClasses(Customer.class);
marshaller.setConverters(new DateConverter());
marshaller.afterPropertiesSet();

Stream Drivers

Configure different XML processing drivers:

import com.thoughtworks.xstream.io.xml.StaxDriver;
import com.thoughtworks.xstream.io.xml.DomDriver;

// Use StAX driver for better performance
marshaller.setStreamDriver(new StaxDriver());

// Or use DOM driver for DOM processing
marshaller.setStreamDriver(new DomDriver());

Usage Examples

Basic Usage

import org.springframework.oxm.xstream.XStreamMarshaller;
import javax.xml.transform.stream.StreamResult;
import javax.xml.transform.stream.StreamSource;
import java.io.StringWriter;
import java.io.StringReader;

// Configure marshaller
XStreamMarshaller marshaller = new XStreamMarshaller();
marshaller.setSupportedClasses(Customer.class);
marshaller.afterPropertiesSet();

// Marshal object to XML
Customer customer = new Customer("John", "Doe");
StringWriter writer = new StringWriter();
marshaller.marshal(customer, new StreamResult(writer));
String xml = writer.toString();

// Unmarshal XML to object
StringReader reader = new StringReader(xml);
Customer unmarshalled = (Customer) marshaller.unmarshal(new StreamSource(reader));

With Custom Configuration

import java.util.HashMap;
import java.util.Map;

XStreamMarshaller marshaller = new XStreamMarshaller();
marshaller.setSupportedClasses(Customer.class, Order.class);

// Configure aliases
Map<String, Class<?>> aliases = new HashMap<>();
aliases.put("customer", Customer.class);
aliases.put("order", Order.class);
marshaller.setAliases(aliases);

// Configure attributes
Map<String, Class<?>> useAttributeFor = new HashMap<>();
useAttributeFor.put("Customer.id", Long.class);
marshaller.setUseAttributeFor(useAttributeFor);

// Configure encoding
marshaller.setEncoding("UTF-8");

marshaller.afterPropertiesSet();

// Use marshaller
Customer customer = new Customer();
customer.setId(123L);
customer.setFirstName("John");

StringWriter writer = new StringWriter();
marshaller.marshal(customer, new StreamResult(writer));
// Results in: <customer id="123"><firstName>John</firstName></customer>

Error Handling

try {
    Customer customer = new Customer();
    StringWriter writer = new StringWriter();
    marshaller.marshal(customer, new StreamResult(writer));
} catch (MarshallingFailureException e) {
    System.err.println("Marshalling failed: " + e.getMessage());
    Throwable cause = e.getCause();
    if (cause instanceof ConversionException) {
        System.err.println("XStream conversion error: " + cause.getMessage());
    }
}

Helper Classes

CatchAllConverter

Utility converter for handling unregistered types:

public class CatchAllConverter implements Converter {
    public boolean canConvert(Class type);
    public void marshal(Object source, HierarchicalStreamWriter writer, 
                       MarshallingContext context);
    public Object unmarshal(HierarchicalStreamReader reader, 
                           UnmarshallingContext context);
}

Security Considerations

XStream has known security vulnerabilities when deserializing untrusted XML. Always:

  1. Use setSupportedClasses() to whitelist allowed classes
  2. Use setTypePermissions() for granular control
  3. Configure appropriate type permissions
  4. Never deserialize XML from untrusted sources without proper security configuration
// Secure configuration example
XStreamMarshaller marshaller = new XStreamMarshaller();

// Explicitly allow only specific classes
marshaller.setSupportedClasses(
    Customer.class, 
    Order.class, 
    String.class,
    java.util.Date.class,
    java.util.ArrayList.class
);

// Security is handled through type permissions and supported classes

marshaller.afterPropertiesSet();

Required Imports

import org.springframework.oxm.xstream.XStreamMarshaller;
import org.springframework.oxm.xstream.CatchAllConverter;
import org.springframework.oxm.MarshallingFailureException;
import org.springframework.oxm.UnmarshallingFailureException;

import com.thoughtworks.xstream.converters.Converter;
import com.thoughtworks.xstream.converters.SingleValueConverter;
import com.thoughtworks.xstream.converters.MarshallingContext;
import com.thoughtworks.xstream.converters.UnmarshallingContext;
import com.thoughtworks.xstream.converters.ConversionException;
import com.thoughtworks.xstream.io.HierarchicalStreamReader;
import com.thoughtworks.xstream.io.HierarchicalStreamWriter;
import com.thoughtworks.xstream.io.xml.StaxDriver;
import com.thoughtworks.xstream.io.xml.DomDriver;
import com.thoughtworks.xstream.security.TypePermission;
import com.thoughtworks.xstream.security.WildcardTypePermission;
import com.thoughtworks.xstream.MarshallingStrategy;

import javax.xml.transform.stream.StreamResult;
import javax.xml.transform.stream.StreamSource;
import java.util.Map;
import java.util.HashMap;

Spring Configuration

XML Configuration

<bean id="xstreamMarshaller" class="org.springframework.oxm.xstream.XStreamMarshaller">
    <property name="supportedClasses">
        <list>
            <value>com.example.Customer</value>
            <value>com.example.Order</value>
        </list>
    </property>
    <property name="aliases">
        <map>
            <entry key="customer" value="com.example.Customer"/>
            <entry key="order" value="com.example.Order"/>
        </map>
    </property>
    <property name="secureProcessing" value="true"/>
</bean>

Java Configuration

@Configuration
public class XStreamConfig {
    
    @Bean
    public XStreamMarshaller xstreamMarshaller() {
        XStreamMarshaller marshaller = new XStreamMarshaller();
        marshaller.setSupportedClasses(Customer.class, Order.class);
        
        Map<String, Class<?>> aliases = new HashMap<>();
        aliases.put("customer", Customer.class);
        marshaller.setAliases(aliases);
        
        marshaller.setSecureProcessing(true);
        return marshaller;
    }
}

Install with Tessl CLI

npx tessl i tessl/maven-org-springframework--spring-oxm

docs

core-marshalling.md

index.md

jaxb-implementation.md

mime-support.md

support-utilities.md

xstream-implementation.md

tile.json