or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

http-abstractions.mdhttp-clients.mdindex.mdmessage-conversion.mdreactive-web.mdweb-binding.mdweb-utilities.md

message-conversion.mddocs/

0

# Message Conversion

1

2

HTTP message conversion and encoding support for transforming between Java objects and HTTP message bodies. Includes both servlet-based converters for traditional web applications and reactive codecs for streaming applications.

3

4

## Capabilities

5

6

### HTTP Message Converters (Servlet-Based)

7

8

Traditional message converters for converting between HTTP messages and Java objects in servlet-based applications.

9

10

```java { .api }

11

/**

12

* Contract for HTTP message converters

13

*/

14

interface HttpMessageConverter<T> {

15

/** Check if this converter can read the given class and media type */

16

boolean canRead(Class<?> clazz, MediaType mediaType);

17

/** Check if this converter can write the given class and media type */

18

boolean canWrite(Class<?> clazz, MediaType mediaType);

19

/** Get the supported media types for this converter */

20

List<MediaType> getSupportedMediaTypes();

21

22

/** Read object from HTTP input message */

23

T read(Class<? extends T> clazz, HttpInputMessage inputMessage)

24

throws IOException, HttpMessageNotReadableException;

25

/** Write object to HTTP output message */

26

void write(T t, MediaType contentType, HttpOutputMessage outputMessage)

27

throws IOException, HttpMessageNotWritableException;

28

}

29

30

/**

31

* Generic version supporting parameterized types

32

*/

33

interface GenericHttpMessageConverter<T> extends HttpMessageConverter<T> {

34

/** Check if converter can read the generic type */

35

boolean canRead(Type type, Class<?> contextClass, MediaType mediaType);

36

/** Check if converter can write the generic type */

37

boolean canWrite(Type type, Class<?> clazz, MediaType mediaType);

38

39

/** Read generic type from HTTP message */

40

T read(Type type, Class<?> contextClass, HttpInputMessage inputMessage)

41

throws IOException, HttpMessageNotReadableException;

42

/** Write generic type to HTTP message */

43

void write(T t, Type type, MediaType contentType, HttpOutputMessage outputMessage)

44

throws IOException, HttpMessageNotWritableException;

45

}

46

```

47

48

### Common Message Converter Implementations

49

50

Built-in converters for common data formats and types.

51

52

```java { .api }

53

/**

54

* Base class for message converter implementations

55

*/

56

abstract class AbstractHttpMessageConverter<T> implements HttpMessageConverter<T> {

57

protected AbstractHttpMessageConverter(MediaType supportedMediaType);

58

protected AbstractHttpMessageConverter(MediaType... supportedMediaTypes);

59

60

/** Set supported media types */

61

void setSupportedMediaTypes(List<MediaType> supportedMediaTypes);

62

/** Get supported media types */

63

List<MediaType> getSupportedMediaTypes();

64

65

// Template methods for subclasses

66

protected abstract boolean supports(Class<?> clazz);

67

protected abstract T readInternal(Class<? extends T> clazz, HttpInputMessage inputMessage)

68

throws IOException, HttpMessageNotReadableException;

69

protected abstract void writeInternal(T t, HttpOutputMessage outputMessage)

70

throws IOException, HttpMessageNotWritableException;

71

}

72

73

/**

74

* String message converter

75

*/

76

class StringHttpMessageConverter extends AbstractHttpMessageConverter<String> {

77

StringHttpMessageConverter();

78

StringHttpMessageConverter(Charset defaultCharset);

79

80

/** Set whether to write Accept-Charset header */

81

void setWriteAcceptCharset(boolean writeAcceptCharset);

82

/** Set available charsets for Accept-Charset header */

83

void setAvailableCharsets(List<Charset> availableCharsets);

84

}

85

86

/**

87

* Byte array message converter

88

*/

89

class ByteArrayHttpMessageConverter extends AbstractHttpMessageConverter<byte[]> {

90

ByteArrayHttpMessageConverter();

91

92

// Supports application/octet-stream and all other media types

93

}

94

95

/**

96

* Resource message converter

97

*/

98

class ResourceHttpMessageConverter extends AbstractHttpMessageConverter<Resource> {

99

ResourceHttpMessageConverter();

100

ResourceHttpMessageConverter(boolean supportsReadStreaming);

101

102

// Automatically detects content type from resource

103

}

104

105

/**

106

* Form data message converter

107

*/

108

class FormHttpMessageConverter implements HttpMessageConverter<MultiValueMap<String, ?>> {

109

FormHttpMessageConverter();

110

111

/** Set default charset for form encoding */

112

void setCharset(Charset charset);

113

/** Set supported media types */

114

void setSupportedMediaTypes(List<MediaType> supportedMediaTypes);

115

/** Set multipart character sets */

116

void setMultipartCharsets(Map<String, Charset> multipartCharsets);

117

}

118

119

/**

120

* Enhanced form converter with multipart support

121

*/

122

class AllEncompassingFormHttpMessageConverter extends FormHttpMessageConverter {

123

AllEncompassingFormHttpMessageConverter();

124

125

// Adds support for multipart/form-data with part converters

126

}

127

```

128

129

### JSON Message Converters

130

131

Converters for JSON serialization using popular libraries.

132

133

```java { .api }

134

/**

135

* Jackson 2 JSON message converter

136

*/

137

class MappingJackson2HttpMessageConverter extends AbstractJackson2HttpMessageConverter {

138

MappingJackson2HttpMessageConverter();

139

MappingJackson2HttpMessageConverter(ObjectMapper objectMapper);

140

141

/** Set the ObjectMapper to use */

142

void setObjectMapper(ObjectMapper objectMapper);

143

/** Get the current ObjectMapper */

144

ObjectMapper getObjectMapper();

145

146

/** Set JSON prefix for security */

147

void setJsonPrefix(String jsonPrefix);

148

/** Set whether to prefix JSON output */

149

void setPrefixJson(boolean prefixJson);

150

}

151

152

/**

153

* Base class for Jackson converters

154

*/

155

abstract class AbstractJackson2HttpMessageConverter extends AbstractGenericHttpMessageConverter<Object> {

156

/** Set pretty print formatting */

157

void setPrettyPrint(boolean prettyPrint);

158

/** Add supported media types */

159

protected void addDefaultMediaTypes(MediaType... mediaTypes);

160

}

161

162

/**

163

* Google Gson JSON message converter

164

*/

165

class GsonHttpMessageConverter extends AbstractGenericHttpMessageConverter<Object> {

166

GsonHttpMessageConverter();

167

GsonHttpMessageConverter(Gson gson);

168

169

/** Set the Gson instance to use */

170

void setGson(Gson gson);

171

/** Get the current Gson instance */

172

Gson getGson();

173

174

/** Set JSON prefix for security */

175

void setJsonPrefix(String jsonPrefix);

176

}

177

178

/**

179

* JSON-B message converter

180

*/

181

class JsonbHttpMessageConverter extends AbstractGenericHttpMessageConverter<Object> {

182

JsonbHttpMessageConverter();

183

JsonbHttpMessageConverter(Jsonb jsonb);

184

185

/** Set the Jsonb instance to use */

186

void setJsonb(Jsonb jsonb);

187

/** Get the current Jsonb instance */

188

Jsonb getJsonb();

189

}

190

```

191

192

### XML Message Converters

193

194

Converters for XML serialization and deserialization.

195

196

```java { .api }

197

/**

198

* JAXB2 XML message converter

199

*/

200

class Jaxb2RootElementHttpMessageConverter extends AbstractJaxb2HttpMessageConverter<Object> {

201

Jaxb2RootElementHttpMessageConverter();

202

203

// Supports classes annotated with @XmlRootElement or @XmlType

204

}

205

206

/**

207

* Marshalling XML message converter using Spring's marshalling abstractions

208

*/

209

class MarshallingHttpMessageConverter extends AbstractHttpMessageConverter<Object> {

210

MarshallingHttpMessageConverter();

211

MarshallingHttpMessageConverter(Marshaller marshaller);

212

MarshallingHttpMessageConverter(Marshaller marshaller, Unmarshaller unmarshaller);

213

214

/** Set the marshaller for writing XML */

215

void setMarshaller(Marshaller marshaller);

216

/** Set the unmarshaller for reading XML */

217

void setUnmarshaller(Unmarshaller unmarshaller);

218

}

219

220

/**

221

* Base class for JAXB2 converters

222

*/

223

abstract class AbstractJaxb2HttpMessageConverter<T> extends AbstractGenericHttpMessageConverter<T> {

224

/** Set whether to process external entities */

225

void setProcessExternalEntities(boolean processExternalEntities);

226

/** Set whether to support DTD parsing */

227

void setSupportDtd(boolean supportDtd);

228

}

229

```

230

231

**Usage Examples:**

232

233

```java

234

// Configure message converters in RestTemplate

235

RestTemplate restTemplate = new RestTemplate();

236

237

// Add custom Jackson converter

238

ObjectMapper objectMapper = new ObjectMapper();

239

objectMapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);

240

MappingJackson2HttpMessageConverter jsonConverter = new MappingJackson2HttpMessageConverter(objectMapper);

241

242

List<HttpMessageConverter<?>> converters = restTemplate.getMessageConverters();

243

converters.add(0, jsonConverter); // Add as first converter

244

245

// Configure form converter

246

FormHttpMessageConverter formConverter = new FormHttpMessageConverter();

247

formConverter.setCharset(StandardCharsets.UTF_8);

248

converters.add(formConverter);

249

250

// Use converters automatically

251

User user = restTemplate.getForObject("/api/users/1", User.class); // Uses JSON converter

252

MultiValueMap<String, String> form = new LinkedMultiValueMap<>();

253

form.add("username", "john");

254

restTemplate.postForObject("/api/login", form, String.class); // Uses form converter

255

```

256

257

### Reactive HTTP Codecs

258

259

Reactive message readers and writers for non-blocking streaming applications.

260

261

```java { .api }

262

/**

263

* Contract to read HTTP messages reactively

264

*/

265

interface HttpMessageReader<T> {

266

/** Check if this reader can read the given type and media type */

267

boolean canRead(ResolvableType elementType, MediaType mediaType);

268

/** Get readable media types */

269

List<MediaType> getReadableMediaTypes();

270

/** Get readable media types for a specific type */

271

default List<MediaType> getReadableMediaTypes(ResolvableType elementType) {

272

return getReadableMediaTypes();

273

}

274

275

/** Read object stream from reactive HTTP input */

276

Flux<T> read(ResolvableType elementType, ReactiveHttpInputMessage message, Map<String, Object> hints);

277

/** Read single object from reactive HTTP input */

278

Mono<T> readMono(ResolvableType elementType, ReactiveHttpInputMessage message, Map<String, Object> hints);

279

}

280

281

/**

282

* Contract to write HTTP messages reactively

283

*/

284

interface HttpMessageWriter<T> {

285

/** Check if this writer can write the given type and media type */

286

boolean canWrite(ResolvableType elementType, MediaType mediaType);

287

/** Get writable media types */

288

List<MediaType> getWritableMediaTypes();

289

/** Get writable media types for a specific type */

290

default List<MediaType> getWritableMediaTypes(ResolvableType elementType) {

291

return getWritableMediaTypes();

292

}

293

294

/** Write object stream to reactive HTTP output */

295

Mono<Void> write(Publisher<? extends T> inputStream, ResolvableType elementType,

296

MediaType mediaType, ReactiveHttpOutputMessage message,

297

Map<String, Object> hints);

298

}

299

```

300

301

### Codec Configuration

302

303

Configuration interfaces for managing HTTP message readers and writers.

304

305

```java { .api }

306

/**

307

* Contract to configure HTTP message readers and writers

308

*/

309

interface CodecConfigurer {

310

/** Configure default codecs */

311

DefaultCodecs defaultCodecs();

312

/** Configure custom codecs */

313

CustomCodecs customCodecs();

314

/** Set whether to register default codecs */

315

void registerDefaults(boolean registerDefaults);

316

317

/** Get configured readers */

318

List<HttpMessageReader<?>> getReaders();

319

/** Get configured writers */

320

List<HttpMessageWriter<?>> getWriters();

321

322

/** Clone this configurer */

323

CodecConfigurer clone();

324

}

325

326

/**

327

* Client-specific codec configurer

328

*/

329

interface ClientCodecConfigurer extends CodecConfigurer {

330

/** Configure default codecs for client use */

331

ClientDefaultCodecs defaultCodecs();

332

333

interface ClientDefaultCodecs extends DefaultCodecs {

334

/** Set max in-memory buffer size */

335

void maxInMemorySize(int byteCount);

336

/** Configure multipart codecs */

337

MultipartCodecs multipartCodecs();

338

/** Set enable logging request details */

339

void enableLoggingRequestDetails(boolean enable);

340

}

341

}

342

343

/**

344

* Server-specific codec configurer

345

*/

346

interface ServerCodecConfigurer extends CodecConfigurer {

347

/** Configure default codecs for server use */

348

ServerDefaultCodecs defaultCodecs();

349

350

interface ServerDefaultCodecs extends DefaultCodecs {

351

/** Set max in-memory buffer size */

352

void maxInMemorySize(int byteCount);

353

/** Configure multipart codecs */

354

MultipartCodecs multipartCodecs();

355

/** Set enable logging request details */

356

void enableLoggingRequestDetails(boolean enable);

357

}

358

}

359

360

/**

361

* Default codec configuration

362

*/

363

interface DefaultCodecs {

364

/** Configure Jackson JSON codec */

365

void jackson2JsonDecoder(Decoder<?> decoder);

366

void jackson2JsonEncoder(Encoder<?> encoder);

367

368

/** Configure Jackson Smile codec */

369

void jackson2SmileDecoder(Decoder<?> decoder);

370

void jackson2SmileEncoder(Encoder<?> encoder);

371

372

/** Configure protobuf codec */

373

void protobufDecoder(Decoder<?> decoder);

374

void protobufEncoder(Encoder<?> encoder);

375

376

/** Configure JAXB2 codec */

377

void jaxb2Decoder(Decoder<?> decoder);

378

void jaxb2Encoder(Encoder<?> encoder);

379

380

/** Configure multipart reader */

381

void multipartReader(HttpMessageReader<?> reader);

382

/** Configure multipart writer */

383

void multipartWriter(HttpMessageWriter<?> writer);

384

}

385

386

/**

387

* Custom codec configuration

388

*/

389

interface CustomCodecs {

390

/** Register custom reader */

391

void register(HttpMessageReader<?> reader);

392

/** Register custom writer */

393

void register(HttpMessageWriter<?> writer);

394

395

/** Register reader with order */

396

void registerWithDefaultConfig(HttpMessageReader<?> reader);

397

/** Register writer with order */

398

void registerWithDefaultConfig(HttpMessageWriter<?> writer);

399

}

400

```

401

402

### Common Reactive Codec Implementations

403

404

Built-in reactive codecs for common data formats.

405

406

```java { .api }

407

/**

408

* Decoder-based HTTP message reader

409

*/

410

class DecoderHttpMessageReader<T> implements HttpMessageReader<T> {

411

DecoderHttpMessageReader(Decoder<T> decoder);

412

413

/** Get the underlying decoder */

414

Decoder<T> getDecoder();

415

}

416

417

/**

418

* Encoder-based HTTP message writer

419

*/

420

class EncoderHttpMessageWriter<T> implements HttpMessageWriter<T> {

421

EncoderHttpMessageWriter(Encoder<T> encoder);

422

423

/** Get the underlying encoder */

424

Encoder<T> getEncoder();

425

}

426

427

/**

428

* Jackson 2 JSON encoder for reactive streams

429

*/

430

class Jackson2JsonEncoder extends Jackson2CodecSupport implements HttpMessageEncoder<Object> {

431

Jackson2JsonEncoder();

432

Jackson2JsonEncoder(ObjectMapper mapper, MimeType... mimeTypes);

433

434

/** Set streaming media types */

435

void setStreamingMediaTypes(List<MediaType> mediaTypes);

436

}

437

438

/**

439

* Jackson 2 JSON decoder for reactive streams

440

*/

441

class Jackson2JsonDecoder extends Jackson2CodecSupport implements HttpMessageDecoder<Object> {

442

Jackson2JsonDecoder();

443

Jackson2JsonDecoder(ObjectMapper mapper, MimeType... mimeTypes);

444

445

/** Set max object count in array */

446

void setMaxInMemorySize(int byteCount);

447

}

448

449

/**

450

* Form data reader for reactive streams

451

*/

452

class FormHttpMessageReader extends LoggingCodecSupport

453

implements HttpMessageReader<MultiValueMap<String, String>> {

454

FormHttpMessageReader();

455

456

/** Set default charset */

457

void setDefaultCharset(Charset defaultCharset);

458

/** Set max in-memory size */

459

void setMaxInMemorySize(int byteCount);

460

}

461

462

/**

463

* Form data writer for reactive streams

464

*/

465

class FormHttpMessageWriter extends LoggingCodecSupport

466

implements HttpMessageWriter<MultiValueMap<String, ?>> {

467

FormHttpMessageWriter();

468

469

/** Set default charset */

470

void setDefaultCharset(Charset defaultCharset);

471

}

472

473

/**

474

* Server-Sent Events reader

475

*/

476

class ServerSentEventHttpMessageReader implements HttpMessageReader<Object> {

477

ServerSentEventHttpMessageReader();

478

ServerSentEventHttpMessageReader(Decoder<?> decoder);

479

480

/** Set max in-memory size */

481

void setMaxInMemorySize(int byteCount);

482

}

483

484

/**

485

* Server-Sent Events writer

486

*/

487

class ServerSentEventHttpMessageWriter implements HttpMessageWriter<Object> {

488

ServerSentEventHttpMessageWriter();

489

ServerSentEventHttpMessageWriter(Encoder<?> encoder);

490

}

491

```

492

493

**Usage Examples:**

494

495

```java

496

// Configure reactive codecs

497

WebClient webClient = WebClient.builder()

498

.codecs(configurer -> {

499

// Configure Jackson

500

configurer.defaultCodecs().jackson2JsonDecoder(

501

new Jackson2JsonDecoder(objectMapper, MediaType.APPLICATION_JSON)

502

);

503

504

// Add custom codec

505

configurer.customCodecs().register(new MyCustomMessageReader());

506

507

// Set buffer limits

508

configurer.defaultCodecs().maxInMemorySize(1024 * 1024); // 1MB

509

})

510

.build();

511

512

// Server codec configuration

513

@Configuration

514

public class WebConfig implements WebFluxConfigurer {

515

@Override

516

public void configureHttpMessageCodecs(ServerCodecConfigurer configurer) {

517

configurer.defaultCodecs().jackson2JsonEncoder(customJsonEncoder());

518

configurer.defaultCodecs().maxInMemorySize(2 * 1024 * 1024); // 2MB

519

}

520

}

521

522

// Use codecs automatically

523

Mono<User> user = webClient.get()

524

.uri("/api/users/1")

525

.retrieve()

526

.bodyToMono(User.class); // Uses JSON decoder

527

528

Flux<String> events = webClient.get()

529

.uri("/api/events")

530

.accept(MediaType.TEXT_EVENT_STREAM)

531

.retrieve()

532

.bodyToFlux(String.class); // Uses SSE reader

533

```

534

535

### Multipart Support

536

537

Support for multipart message processing in both servlet and reactive environments.

538

539

```java { .api }

540

/**

541

* Multipart HTTP message reader

542

*/

543

class MultipartHttpMessageReader implements HttpMessageReader<MultiValueMap<String, Part>> {

544

MultipartHttpMessageReader();

545

MultipartHttpMessageReader(HttpMessageReader<?> partReader);

546

547

/** Set max parts count */

548

void setMaxParts(int maxParts);

549

/** Set max disk usage per part */

550

void setMaxDiskUsagePerPart(long maxDiskUsagePerPart);

551

/** Set max memory per part */

552

void setMaxInMemorySize(int maxInMemorySize);

553

/** Set streaming media types */

554

void setStreamingMediaTypes(List<MediaType> streamingMediaTypes);

555

}

556

557

/**

558

* Multipart HTTP message writer

559

*/

560

class MultipartHttpMessageWriter implements HttpMessageWriter<MultiValueMap<String, ?>> {

561

MultipartHttpMessageWriter();

562

MultipartHttpMessageWriter(List<HttpMessageWriter<?>> partWriters);

563

564

/** Set boundary generation strategy */

565

void setBoundaryGenerator(Supplier<String> boundaryGenerator);

566

/** Set multipart charset */

567

void setCharset(Charset charset);

568

}

569

570

/**

571

* Part interface for multipart content

572

*/

573

interface Part {

574

/** Get part name */

575

String name();

576

/** Get part headers */

577

HttpHeaders headers();

578

/** Get part content as data buffer flux */

579

Flux<DataBuffer> content();

580

}

581

582

/**

583

* File part for multipart file uploads

584

*/

585

interface FilePart extends Part {

586

/** Get original filename */

587

String filename();

588

/** Transfer part content to file */

589

Mono<Void> transferTo(Path dest);

590

/** Transfer part content to file */

591

Mono<Void> transferTo(File dest);

592

}

593

594

/**

595

* Form field part for multipart forms

596

*/

597

interface FormFieldPart extends Part {

598

/** Get form field value */

599

String value();

600

}

601

```

602

603

**Usage Examples:**

604

605

```java

606

// Handle multipart upload in reactive controller

607

@PostMapping(value = "/upload", consumes = MediaType.MULTIPART_FORM_DATA_VALUE)

608

public Mono<String> handleUpload(@RequestPart("file") Mono<FilePart> filePartMono) {

609

return filePartMono

610

.flatMap(part -> part.transferTo(Paths.get("/uploads/" + part.filename())))

611

.then(Mono.just("File uploaded successfully"));

612

}

613

614

// Send multipart request with WebClient

615

MultiValueMap<String, Object> parts = new LinkedMultiValueMap<>();

616

parts.add("field", "value");

617

parts.add("file", new FileSystemResource("/path/to/file.txt"));

618

619

Mono<String> response = webClient.post()

620

.uri("/api/upload")

621

.contentType(MediaType.MULTIPART_FORM_DATA)

622

.body(BodyInserters.fromMultipartData(parts))

623

.retrieve()

624

.bodyToMono(String.class);

625

```

626

627

## Exception Handling

628

629

Exception types thrown during message conversion and processing.

630

631

```java { .api }

632

/**

633

* Exception thrown when message conversion fails during reading

634

*/

635

class HttpMessageNotReadableException extends HttpMessageConversionException {

636

HttpMessageNotReadableException(String msg);

637

HttpMessageNotReadableException(String msg, Throwable cause);

638

HttpMessageNotReadableException(String msg, HttpInputMessage httpInputMessage);

639

HttpMessageNotReadableException(String msg, Throwable cause, HttpInputMessage httpInputMessage);

640

}

641

642

/**

643

* Exception thrown when message conversion fails during writing

644

*/

645

class HttpMessageNotWritableException extends HttpMessageConversionException {

646

HttpMessageNotWritableException(String msg);

647

HttpMessageNotWritableException(String msg, Throwable cause);

648

}

649

650

/**

651

* Base exception for message conversion issues

652

*/

653

abstract class HttpMessageConversionException extends NestedRuntimeException {

654

HttpMessageConversionException(String msg);

655

HttpMessageConversionException(String msg, Throwable cause);

656

}

657

```