or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

core-marshalling.mdindex.mdjaxb-implementation.mdmime-support.mdsupport-utilities.mdxstream-implementation.md

xstream-implementation.mddocs/

0

# XStream Implementation

1

2

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.

3

4

## Core Class

5

6

### XStreamMarshaller

7

8

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

9

10

```java { .api }

11

public class XStreamMarshaller extends AbstractMarshaller implements BeanClassLoaderAware, InitializingBean {

12

13

// Configuration Methods

14

public void setSupportedClasses(Class<?>... supportedClasses);

15

public void setTypePermissions(TypePermission... typePermissions);

16

public void setConverters(ConverterMatcher... converters);

17

public void setMarshallingStrategy(MarshallingStrategy marshallingStrategy);

18

public void setMode(int mode);

19

public void setAliases(Map<String, ?> aliases);

20

public void setAliasesByType(Map<Class<?>, String> aliasesByType);

21

public void setFieldAliases(Map<String, String> fieldAliases);

22

public void setUseAttributeFor(Map<?, ?> useAttributeFor);

23

public void setUseAttributeForTypes(Class<?>... useAttributeForTypes);

24

public void setImplicitCollections(Map<Class<?>, String> implicitCollections);

25

public void setOmittedFields(Map<Class<?>, String> omittedFields);

26

public void setStreamDriver(HierarchicalStreamDriver streamDriver);

27

public void setEncoding(String encoding);

28

public void setClassLoader(ClassLoader classLoader);

29

public void setAutodetectAnnotations(boolean autodetectAnnotations);

30

public void setReflectionProvider(ReflectionProvider reflectionProvider);

31

public void setMapperWrappers(Class<? extends MapperWrapper>... mapperWrappers);

32

33

// Security Methods - Type permissions and supported classes provide security controls

34

35

// Inherited methods

36

public boolean supports(Class<?> clazz);

37

public void marshal(Object graph, Result result) throws IOException, XmlMappingException;

38

public Object unmarshal(Source source) throws IOException, XmlMappingException;

39

}

40

```

41

42

## Configuration Options

43

44

### Basic Configuration

45

46

```java

47

import org.springframework.oxm.xstream.XStreamMarshaller;

48

49

XStreamMarshaller marshaller = new XStreamMarshaller();

50

51

// Specify supported classes for security

52

marshaller.setSupportedClasses(Customer.class, Order.class, Product.class);

53

54

// Initialize the marshaller

55

marshaller.afterPropertiesSet();

56

```

57

58

### Security Configuration

59

60

XStream requires explicit security configuration to prevent deserialization vulnerabilities:

61

62

```java

63

import com.thoughtworks.xstream.security.TypePermission;

64

import com.thoughtworks.xstream.security.WildcardTypePermission;

65

66

XStreamMarshaller marshaller = new XStreamMarshaller();

67

68

// Option 1: Use supported classes (recommended)

69

marshaller.setSupportedClasses(Customer.class, Order.class);

70

71

// Option 2: Use type permissions for more granular control

72

TypePermission[] permissions = {

73

new WildcardTypePermission(new String[]{"com.example.model.**"}),

74

new WildcardTypePermission(new String[]{"java.util.**"})

75

};

76

marshaller.setTypePermissions(permissions);

77

78

// Security is handled through type permissions and supported classes

79

80

marshaller.afterPropertiesSet();

81

```

82

83

### Aliases and Field Mapping

84

85

Customize XML element names and structure:

86

87

```java

88

import java.util.HashMap;

89

import java.util.Map;

90

91

XStreamMarshaller marshaller = new XStreamMarshaller();

92

marshaller.setSupportedClasses(Customer.class, Order.class);

93

94

// Class aliases (changes root element name)

95

Map<String, Class<?>> aliases = new HashMap<>();

96

aliases.put("customer", Customer.class);

97

aliases.put("order", Order.class);

98

marshaller.setAliases(aliases);

99

100

// Type-based aliases

101

Map<Class<?>, String> aliasesByType = new HashMap<>();

102

aliasesByType.put(Customer.class, "customer");

103

marshaller.setAliasesByType(aliasesByType);

104

105

// Field aliases (changes property names)

106

Map<String, String> fieldAliases = new HashMap<>();

107

fieldAliases.put("Customer.firstName", "fname");

108

fieldAliases.put("Customer.lastName", "lname");

109

marshaller.setFieldAliases(fieldAliases);

110

111

marshaller.afterPropertiesSet();

112

```

113

114

### Attribute Mapping

115

116

Configure which fields should be XML attributes instead of elements:

117

118

```java

119

Map<String, Class<?>> useAttributeFor = new HashMap<>();

120

useAttributeFor.put("Customer.id", String.class);

121

useAttributeFor.put("Order.status", String.class);

122

marshaller.setUseAttributeFor(useAttributeFor);

123

124

// Or specify by type

125

marshaller.setUseAttributeForTypes(Long.class, Integer.class);

126

```

127

128

### Collection Handling

129

130

Configure implicit collections to avoid wrapper elements:

131

132

```java

133

Map<Class<?>, String> implicitCollections = new HashMap<>();

134

implicitCollections.put(Order.class, "items");

135

implicitCollections.put(Customer.class, "addresses");

136

marshaller.setImplicitCollections(implicitCollections);

137

```

138

139

### Custom Converters

140

141

Implement custom conversion logic for specific types:

142

143

```java

144

import com.thoughtworks.xstream.converters.Converter;

145

import com.thoughtworks.xstream.converters.MarshallingContext;

146

import com.thoughtworks.xstream.converters.UnmarshallingContext;

147

import com.thoughtworks.xstream.io.HierarchicalStreamReader;

148

import com.thoughtworks.xstream.io.HierarchicalStreamWriter;

149

150

public class DateConverter implements Converter {

151

private SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd");

152

153

@Override

154

public boolean canConvert(Class type) {

155

return Date.class.isAssignableFrom(type);

156

}

157

158

@Override

159

public void marshal(Object source, HierarchicalStreamWriter writer,

160

MarshallingContext context) {

161

Date date = (Date) source;

162

writer.setValue(dateFormat.format(date));

163

}

164

165

@Override

166

public Object unmarshal(HierarchicalStreamReader reader,

167

UnmarshallingContext context) {

168

try {

169

return dateFormat.parse(reader.getValue());

170

} catch (ParseException e) {

171

throw new ConversionException("Cannot parse date", e);

172

}

173

}

174

}

175

176

// Configure marshaller with custom converter

177

XStreamMarshaller marshaller = new XStreamMarshaller();

178

marshaller.setSupportedClasses(Customer.class);

179

marshaller.setConverters(new DateConverter());

180

marshaller.afterPropertiesSet();

181

```

182

183

### Stream Drivers

184

185

Configure different XML processing drivers:

186

187

```java

188

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

189

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

190

191

// Use StAX driver for better performance

192

marshaller.setStreamDriver(new StaxDriver());

193

194

// Or use DOM driver for DOM processing

195

marshaller.setStreamDriver(new DomDriver());

196

```

197

198

## Usage Examples

199

200

### Basic Usage

201

202

```java

203

import org.springframework.oxm.xstream.XStreamMarshaller;

204

import javax.xml.transform.stream.StreamResult;

205

import javax.xml.transform.stream.StreamSource;

206

import java.io.StringWriter;

207

import java.io.StringReader;

208

209

// Configure marshaller

210

XStreamMarshaller marshaller = new XStreamMarshaller();

211

marshaller.setSupportedClasses(Customer.class);

212

marshaller.afterPropertiesSet();

213

214

// Marshal object to XML

215

Customer customer = new Customer("John", "Doe");

216

StringWriter writer = new StringWriter();

217

marshaller.marshal(customer, new StreamResult(writer));

218

String xml = writer.toString();

219

220

// Unmarshal XML to object

221

StringReader reader = new StringReader(xml);

222

Customer unmarshalled = (Customer) marshaller.unmarshal(new StreamSource(reader));

223

```

224

225

### With Custom Configuration

226

227

```java

228

import java.util.HashMap;

229

import java.util.Map;

230

231

XStreamMarshaller marshaller = new XStreamMarshaller();

232

marshaller.setSupportedClasses(Customer.class, Order.class);

233

234

// Configure aliases

235

Map<String, Class<?>> aliases = new HashMap<>();

236

aliases.put("customer", Customer.class);

237

aliases.put("order", Order.class);

238

marshaller.setAliases(aliases);

239

240

// Configure attributes

241

Map<String, Class<?>> useAttributeFor = new HashMap<>();

242

useAttributeFor.put("Customer.id", Long.class);

243

marshaller.setUseAttributeFor(useAttributeFor);

244

245

// Configure encoding

246

marshaller.setEncoding("UTF-8");

247

248

marshaller.afterPropertiesSet();

249

250

// Use marshaller

251

Customer customer = new Customer();

252

customer.setId(123L);

253

customer.setFirstName("John");

254

255

StringWriter writer = new StringWriter();

256

marshaller.marshal(customer, new StreamResult(writer));

257

// Results in: <customer id="123"><firstName>John</firstName></customer>

258

```

259

260

### Error Handling

261

262

```java

263

try {

264

Customer customer = new Customer();

265

StringWriter writer = new StringWriter();

266

marshaller.marshal(customer, new StreamResult(writer));

267

} catch (MarshallingFailureException e) {

268

System.err.println("Marshalling failed: " + e.getMessage());

269

Throwable cause = e.getCause();

270

if (cause instanceof ConversionException) {

271

System.err.println("XStream conversion error: " + cause.getMessage());

272

}

273

}

274

```

275

276

## Helper Classes

277

278

### CatchAllConverter

279

280

Utility converter for handling unregistered types:

281

282

```java { .api }

283

public class CatchAllConverter implements Converter {

284

public boolean canConvert(Class type);

285

public void marshal(Object source, HierarchicalStreamWriter writer,

286

MarshallingContext context);

287

public Object unmarshal(HierarchicalStreamReader reader,

288

UnmarshallingContext context);

289

}

290

```

291

292

## Security Considerations

293

294

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

295

296

1. Use `setSupportedClasses()` to whitelist allowed classes

297

2. Use `setTypePermissions()` for granular control

298

3. Configure appropriate type permissions

299

4. Never deserialize XML from untrusted sources without proper security configuration

300

301

```java

302

// Secure configuration example

303

XStreamMarshaller marshaller = new XStreamMarshaller();

304

305

// Explicitly allow only specific classes

306

marshaller.setSupportedClasses(

307

Customer.class,

308

Order.class,

309

String.class,

310

java.util.Date.class,

311

java.util.ArrayList.class

312

);

313

314

// Security is handled through type permissions and supported classes

315

316

marshaller.afterPropertiesSet();

317

```

318

319

## Required Imports

320

321

```java

322

import org.springframework.oxm.xstream.XStreamMarshaller;

323

import org.springframework.oxm.xstream.CatchAllConverter;

324

import org.springframework.oxm.MarshallingFailureException;

325

import org.springframework.oxm.UnmarshallingFailureException;

326

327

import com.thoughtworks.xstream.converters.Converter;

328

import com.thoughtworks.xstream.converters.SingleValueConverter;

329

import com.thoughtworks.xstream.converters.MarshallingContext;

330

import com.thoughtworks.xstream.converters.UnmarshallingContext;

331

import com.thoughtworks.xstream.converters.ConversionException;

332

import com.thoughtworks.xstream.io.HierarchicalStreamReader;

333

import com.thoughtworks.xstream.io.HierarchicalStreamWriter;

334

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

335

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

336

import com.thoughtworks.xstream.security.TypePermission;

337

import com.thoughtworks.xstream.security.WildcardTypePermission;

338

import com.thoughtworks.xstream.MarshallingStrategy;

339

340

import javax.xml.transform.stream.StreamResult;

341

import javax.xml.transform.stream.StreamSource;

342

import java.util.Map;

343

import java.util.HashMap;

344

```

345

346

## Spring Configuration

347

348

### XML Configuration

349

350

```xml

351

<bean id="xstreamMarshaller" class="org.springframework.oxm.xstream.XStreamMarshaller">

352

<property name="supportedClasses">

353

<list>

354

<value>com.example.Customer</value>

355

<value>com.example.Order</value>

356

</list>

357

</property>

358

<property name="aliases">

359

<map>

360

<entry key="customer" value="com.example.Customer"/>

361

<entry key="order" value="com.example.Order"/>

362

</map>

363

</property>

364

<property name="secureProcessing" value="true"/>

365

</bean>

366

```

367

368

### Java Configuration

369

370

```java

371

@Configuration

372

public class XStreamConfig {

373

374

@Bean

375

public XStreamMarshaller xstreamMarshaller() {

376

XStreamMarshaller marshaller = new XStreamMarshaller();

377

marshaller.setSupportedClasses(Customer.class, Order.class);

378

379

Map<String, Class<?>> aliases = new HashMap<>();

380

aliases.put("customer", Customer.class);

381

marshaller.setAliases(aliases);

382

383

marshaller.setSecureProcessing(true);

384

return marshaller;

385

}

386

}

387

```