or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

core-utilities.mdcryptography.mdfunctional-programming.mdgenerators.mdhttp-clients.mdindex.mdjwt-utilities.mdserialization.mdspecialized-utilities.mdspring-integration.mdtext-processing.md

serialization.mddocs/

0

# Serialization

1

2

Object serialization utilities with support for various formats, compression, encryption, and Jackson integration for secure and efficient data persistence and transmission.

3

4

## SerializationUtils

5

6

Core utility class providing comprehensive serialization operations with support for encryption and encoding.

7

8

```java { .api }

9

@UtilityClass

10

public class SerializationUtils {

11

12

// Basic serialization operations

13

public static byte[] serialize(Serializable object);

14

public static void serialize(Serializable object, OutputStream outputStream);

15

16

// Basic deserialization operations

17

public static <T> T deserialize(byte[] inBytes, Class<T> clazz);

18

public static <T> T deserialize(InputStream inputStream, Class<T> clazz);

19

20

// Encrypted serialization operations

21

public static byte[] serializeAndEncodeObject(EncodableCipher cipher,

22

Serializable object,

23

Object[] parameters);

24

25

public static byte[] serializeAndEncodeObject(EncodableCipher cipher,

26

Serializable object);

27

28

// Encrypted deserialization operations

29

public static <T extends Serializable> T decodeAndDeserializeObject(

30

byte[] object,

31

Class<T> type,

32

DecodableCipher cipher,

33

Object[] parameters

34

);

35

36

public static <T extends Serializable> T decodeAndDeserializeObject(

37

byte[] object,

38

Class<T> type,

39

DecodableCipher cipher

40

);

41

42

// Validation and safety operations

43

public static <T extends Serializable> T deserializeAndCheckObject(

44

byte[] object,

45

Class<T> type

46

);

47

}

48

```

49

50

### Usage Examples

51

52

**Basic serialization operations:**

53

```java

54

@Service

55

public class CacheService {

56

57

public void storeUserSession(String sessionId, UserSession session) {

58

try {

59

// Serialize user session

60

byte[] serialized = SerializationUtils.serialize(session);

61

62

// Store in cache/database

63

cacheManager.put(sessionId, serialized);

64

65

} catch (Exception e) {

66

log.error("Failed to serialize user session", e);

67

throw new SerializationException("Session storage failed", e);

68

}

69

}

70

71

public Optional<UserSession> retrieveUserSession(String sessionId) {

72

try {

73

byte[] data = cacheManager.get(sessionId);

74

if (data != null) {

75

UserSession session = SerializationUtils.deserialize(data, UserSession.class);

76

return Optional.of(session);

77

}

78

return Optional.empty();

79

80

} catch (Exception e) {

81

log.error("Failed to deserialize user session", e);

82

return Optional.empty();

83

}

84

}

85

86

public void persistToFile(Serializable object, Path filePath) {

87

try (FileOutputStream fos = new FileOutputStream(filePath.toFile())) {

88

SerializationUtils.serialize(object, fos);

89

} catch (Exception e) {

90

log.error("Failed to persist object to file", e);

91

throw new SerializationException("File persistence failed", e);

92

}

93

}

94

95

public <T> Optional<T> loadFromFile(Path filePath, Class<T> type) {

96

try (FileInputStream fis = new FileInputStream(filePath.toFile())) {

97

T object = SerializationUtils.deserialize(fis, type);

98

return Optional.of(object);

99

} catch (Exception e) {

100

log.error("Failed to load object from file", e);

101

return Optional.empty();

102

}

103

}

104

}

105

```

106

107

**Encrypted serialization for sensitive data:**

108

```java

109

@Service

110

public class SecureDataService {

111

112

private final CipherExecutor<Serializable, byte[]> cipher;

113

114

public SecureDataService(CipherExecutor<Serializable, byte[]> cipher) {

115

this.cipher = cipher;

116

}

117

118

public void storeSecureData(String key, SensitiveData data) {

119

try {

120

// Serialize and encrypt in one operation

121

byte[] encrypted = SerializationUtils.serializeAndEncodeObject(cipher, data);

122

123

// Store encrypted data

124

secureStorage.store(key, encrypted);

125

126

log.info("Securely stored data for key: {}", key);

127

128

} catch (Exception e) {

129

log.error("Failed to store secure data", e);

130

throw new SecurityException("Secure storage failed", e);

131

}

132

}

133

134

public Optional<SensitiveData> retrieveSecureData(String key) {

135

try {

136

byte[] encrypted = secureStorage.retrieve(key);

137

if (encrypted != null) {

138

// Decrypt and deserialize in one operation

139

SensitiveData data = SerializationUtils.decodeAndDeserializeObject(

140

encrypted,

141

SensitiveData.class,

142

cipher

143

);

144

return Optional.of(data);

145

}

146

return Optional.empty();

147

148

} catch (Exception e) {

149

log.error("Failed to retrieve secure data", e);

150

return Optional.empty();

151

}

152

}

153

154

public void storeWithParameters(String key, ConfigurableData data, String[] params) {

155

try {

156

// Use cipher parameters for additional security context

157

Object[] cipherParams = Arrays.stream(params)

158

.map(String::getBytes)

159

.toArray();

160

161

byte[] encrypted = SerializationUtils.serializeAndEncodeObject(

162

cipher,

163

data,

164

cipherParams

165

);

166

167

secureStorage.store(key, encrypted);

168

169

} catch (Exception e) {

170

log.error("Failed to store configurable data", e);

171

throw new SecurityException("Parameterized storage failed", e);

172

}

173

}

174

}

175

```

176

177

**Safe deserialization with validation:**

178

```java

179

@Component

180

public class SafeDeserializationService {

181

182

private final Set<Class<?>> allowedClasses;

183

184

public SafeDeserializationService() {

185

// Whitelist of allowed classes for deserialization

186

this.allowedClasses = Set.of(

187

UserSession.class,

188

AuthenticationToken.class,

189

ServiceTicket.class,

190

CacheEntry.class

191

);

192

}

193

194

public <T extends Serializable> Optional<T> safeDeserialize(byte[] data, Class<T> type) {

195

// Validate class is allowed

196

if (!isAllowedClass(type)) {

197

log.warn("Attempted to deserialize disallowed class: {}", type.getName());

198

return Optional.empty();

199

}

200

201

try {

202

// Use safe deserialization with validation

203

T object = SerializationUtils.deserializeAndCheckObject(data, type);

204

205

// Additional validation

206

if (isValidObject(object)) {

207

return Optional.of(object);

208

} else {

209

log.warn("Deserialized object failed validation: {}", type.getName());

210

return Optional.empty();

211

}

212

213

} catch (Exception e) {

214

log.error("Safe deserialization failed for type: {}", type.getName(), e);

215

return Optional.empty();

216

}

217

}

218

219

private boolean isAllowedClass(Class<?> clazz) {

220

return allowedClasses.contains(clazz) ||

221

allowedClasses.stream().anyMatch(allowed -> allowed.isAssignableFrom(clazz));

222

}

223

224

private boolean isValidObject(Object object) {

225

// Implement business logic validation

226

if (object instanceof UserSession session) {

227

return session.getUserId() != null && session.getCreatedAt() != null;

228

}

229

230

if (object instanceof AuthenticationToken token) {

231

return token.getToken() != null && token.getExpiresAt() > System.currentTimeMillis();

232

}

233

234

return true; // Default validation

235

}

236

}

237

```

238

239

## Jackson Integration

240

241

### BaseJacksonSerializer

242

243

Abstract Jackson-based serializer providing customizable JSON serialization.

244

245

```java { .api }

246

public abstract class BaseJacksonSerializer<T> {

247

248

// Jackson ObjectMapper instance

249

protected final ObjectMapper objectMapper;

250

251

// Constructor

252

protected BaseJacksonSerializer(ObjectMapper objectMapper);

253

254

// Serialization methods

255

public String serialize(T object);

256

public byte[] serializeToBytes(T object);

257

public void serializeToStream(T object, OutputStream outputStream);

258

259

// Deserialization methods

260

public T deserialize(String json);

261

public T deserialize(byte[] data);

262

public T deserialize(InputStream inputStream);

263

264

// Abstract methods for subclasses

265

protected abstract Class<T> getObjectType();

266

protected abstract void configureObjectMapper(ObjectMapper mapper);

267

}

268

```

269

270

### JacksonObjectMapperFactory

271

272

Factory for creating and configuring Jackson ObjectMapper instances with CAS-specific settings.

273

274

```java { .api }

275

public class JacksonObjectMapperFactory {

276

277

// Factory methods

278

public static ObjectMapper builder();

279

public static ObjectMapper builder(boolean defaultTypingEnabled);

280

281

// Configuration methods

282

public static ObjectMapper configure(ObjectMapper mapper);

283

public static ObjectMapper configureForCas(ObjectMapper mapper);

284

285

// Specialized configurations

286

public static ObjectMapper createForTickets();

287

public static ObjectMapper createForServices();

288

public static ObjectMapper createForAuthentication();

289

290

// Feature configuration

291

public static ObjectMapper withFeature(ObjectMapper mapper,

292

SerializationFeature feature,

293

boolean enabled);

294

295

public static ObjectMapper withFeature(ObjectMapper mapper,

296

DeserializationFeature feature,

297

boolean enabled);

298

}

299

```

300

301

### Usage Examples

302

303

**Custom Jackson serializer implementation:**

304

```java

305

@Component

306

public class UserSessionSerializer extends BaseJacksonSerializer<UserSession> {

307

308

public UserSessionSerializer() {

309

super(JacksonObjectMapperFactory.builder());

310

}

311

312

@Override

313

protected Class<UserSession> getObjectType() {

314

return UserSession.class;

315

}

316

317

@Override

318

protected void configureObjectMapper(ObjectMapper mapper) {

319

// Custom configuration for user sessions

320

mapper.configure(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS, false);

321

mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);

322

323

// Custom date format

324

mapper.setDateFormat(new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSSZ"));

325

326

// Include type information for polymorphic handling

327

mapper.activateDefaultTyping(

328

LaissezFaireSubTypeValidator.instance,

329

ObjectMapper.DefaultTyping.NON_FINAL

330

);

331

332

// Custom modules

333

mapper.registerModule(new JavaTimeModule());

334

mapper.registerModule(new CasJacksonModule());

335

}

336

}

337

```

338

339

**Factory usage for different contexts:**

340

```java

341

@Configuration

342

public class SerializationConfiguration {

343

344

@Bean("ticketObjectMapper")

345

public ObjectMapper ticketObjectMapper() {

346

ObjectMapper mapper = JacksonObjectMapperFactory.createForTickets();

347

348

// Additional ticket-specific configuration

349

mapper.configure(SerializationFeature.FAIL_ON_EMPTY_BEANS, false);

350

mapper.configure(DeserializationFeature.ACCEPT_EMPTY_STRING_AS_NULL_OBJECT, true);

351

352

return mapper;

353

}

354

355

@Bean("serviceObjectMapper")

356

public ObjectMapper serviceObjectMapper() {

357

ObjectMapper mapper = JacksonObjectMapperFactory.createForServices();

358

359

// Service registry specific settings

360

mapper.configure(SerializationFeature.INDENT_OUTPUT, true);

361

mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);

362

363

return mapper;

364

}

365

366

@Bean("authenticationObjectMapper")

367

public ObjectMapper authenticationObjectMapper() {

368

ObjectMapper mapper = JacksonObjectMapperFactory.createForAuthentication();

369

370

// Security-focused configuration

371

mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, true);

372

mapper.configure(JsonParser.Feature.STRICT_DUPLICATE_DETECTION, true);

373

374

return mapper;

375

}

376

}

377

```

378

379

## DefaultComponentSerializationPlan

380

381

Default serialization plan for component-based serialization strategies.

382

383

```java { .api }

384

public class DefaultComponentSerializationPlan implements ComponentSerializationPlan {

385

386

// Serialization strategy configuration

387

private final Map<Class<?>, SerializationStrategy> strategies;

388

389

// Constructor

390

public DefaultComponentSerializationPlan();

391

public DefaultComponentSerializationPlan(Map<Class<?>, SerializationStrategy> strategies);

392

393

// Plan execution

394

@Override

395

public byte[] serialize(Object object);

396

397

@Override

398

public <T> T deserialize(byte[] data, Class<T> type);

399

400

// Strategy management

401

public void registerStrategy(Class<?> type, SerializationStrategy strategy);

402

public void removeStrategy(Class<?> type);

403

public SerializationStrategy getStrategy(Class<?> type);

404

}

405

```

406

407

### Usage Examples

408

409

**Component serialization plan:**

410

```java

411

@Configuration

412

public class SerializationPlanConfiguration {

413

414

@Bean

415

public ComponentSerializationPlan casSerializationPlan() {

416

Map<Class<?>, SerializationStrategy> strategies = new HashMap<>();

417

418

// Different strategies for different types

419

strategies.put(UserSession.class, new JacksonSerializationStrategy());

420

strategies.put(ServiceTicket.class, new CompactBinaryStrategy());

421

strategies.put(AuthenticationToken.class, new EncryptedJsonStrategy());

422

strategies.put(CacheEntry.class, new CompressedSerializationStrategy());

423

424

DefaultComponentSerializationPlan plan = new DefaultComponentSerializationPlan(strategies);

425

426

// Register additional strategies

427

plan.registerStrategy(RegisteredService.class, new ServiceJsonStrategy());

428

429

return plan;

430

}

431

}

432

433

@Service

434

public class ComponentSerializationService {

435

436

private final ComponentSerializationPlan serializationPlan;

437

438

public byte[] serializeComponent(Object component) {

439

return serializationPlan.serialize(component);

440

}

441

442

public <T> T deserializeComponent(byte[] data, Class<T> type) {

443

return serializationPlan.deserialize(data, type);

444

}

445

}

446

```

447

448

## JacksonInjectableValueSupplier

449

450

Injectable value supplier for providing runtime values during Jackson deserialization.

451

452

```java { .api }

453

public class JacksonInjectableValueSupplier extends InjectableValues {

454

455

// Value providers

456

private final Map<String, Supplier<Object>> valueSuppliers;

457

private final ApplicationContext applicationContext;

458

459

// Constructor

460

public JacksonInjectableValueSupplier(ApplicationContext applicationContext);

461

462

// Value injection

463

@Override

464

public Object findInjectableValue(Object valueId,

465

DeserializationContext ctxt,

466

BeanProperty forProperty,

467

Object beanInstance);

468

469

// Supplier registration

470

public void registerSupplier(String valueId, Supplier<Object> supplier);

471

public void registerBean(String valueId, Class<?> beanType);

472

public void registerConstant(String valueId, Object value);

473

}

474

```

475

476

### Usage Examples

477

478

**Injectable value configuration:**

479

```java

480

@Configuration

481

public class JacksonInjectableConfiguration {

482

483

@Bean

484

public JacksonInjectableValueSupplier injectableValueSupplier(ApplicationContext context) {

485

JacksonInjectableValueSupplier supplier = new JacksonInjectableValueSupplier(context);

486

487

// Register runtime suppliers

488

supplier.registerSupplier("currentTime", System::currentTimeMillis);

489

supplier.registerSupplier("serverId", () -> getServerId());

490

supplier.registerSupplier("environment", () -> getEnvironment());

491

492

// Register Spring beans for injection

493

supplier.registerBean("userService", UserService.class);

494

supplier.registerBean("cacheManager", CacheManager.class);

495

496

// Register constants

497

supplier.registerConstant("version", "7.2.4");

498

supplier.registerConstant("deployment", "production");

499

500

return supplier;

501

}

502

503

@Bean

504

public ObjectMapper injectableObjectMapper(JacksonInjectableValueSupplier supplier) {

505

ObjectMapper mapper = JacksonObjectMapperFactory.builder();

506

mapper.setInjectableValues(supplier);

507

return mapper;

508

}

509

}

510

511

// Usage in domain objects

512

public class AuditableEntity {

513

514

@JsonProperty

515

private String id;

516

517

@JacksonInject("currentTime")

518

private Long createdAt;

519

520

@JacksonInject("serverId")

521

private String serverId;

522

523

@JacksonInject("userService")

524

private transient UserService userService;

525

526

// getters/setters

527

}

528

```

529

530

## PatternJsonDeserializer

531

532

Pattern-based JSON deserializer for handling regular expressions and pattern objects.

533

534

```java { .api }

535

public class PatternJsonDeserializer extends JsonDeserializer<Pattern> {

536

537

@Override

538

public Pattern deserialize(JsonParser parser,

539

DeserializationContext context) throws IOException;

540

541

// Pattern compilation options

542

public Pattern deserializeWithFlags(JsonParser parser,

543

DeserializationContext context,

544

int flags) throws IOException;

545

}

546

```

547

548

### Complete Integration Example

549

550

```java

551

@Service

552

@Slf4j

553

public class ComprehensiveSerializationService {

554

555

private final ObjectMapper jacksonMapper;

556

private final CipherExecutor<Serializable, byte[]> cipher;

557

private final ComponentSerializationPlan serializationPlan;

558

559

public ComprehensiveSerializationService(

560

@Qualifier("casObjectMapper") ObjectMapper jacksonMapper,

561

CipherExecutor<Serializable, byte[]> cipher,

562

ComponentSerializationPlan serializationPlan) {

563

564

this.jacksonMapper = jacksonMapper;

565

this.cipher = cipher;

566

this.serializationPlan = serializationPlan;

567

}

568

569

// JSON serialization for web APIs

570

public String toJson(Object object) {

571

try {

572

return jacksonMapper.writeValueAsString(object);

573

} catch (JsonProcessingException e) {

574

log.error("JSON serialization failed", e);

575

throw new SerializationException("JSON conversion failed", e);

576

}

577

}

578

579

public <T> T fromJson(String json, Class<T> type) {

580

try {

581

return jacksonMapper.readValue(json, type);

582

} catch (JsonProcessingException e) {

583

log.error("JSON deserialization failed", e);

584

throw new SerializationException("JSON parsing failed", e);

585

}

586

}

587

588

// Binary serialization for caching

589

public byte[] toBinary(Serializable object) {

590

return SerializationUtils.serialize(object);

591

}

592

593

public <T> T fromBinary(byte[] data, Class<T> type) {

594

return SerializationUtils.deserialize(data, type);

595

}

596

597

// Encrypted serialization for sensitive data

598

public byte[] toEncryptedBinary(Serializable object) {

599

return SerializationUtils.serializeAndEncodeObject(cipher, object);

600

}

601

602

public <T extends Serializable> T fromEncryptedBinary(byte[] data, Class<T> type) {

603

return SerializationUtils.decodeAndDeserializeObject(data, type, cipher);

604

}

605

606

// Component-based serialization

607

public byte[] serializeComponent(Object component) {

608

return serializationPlan.serialize(component);

609

}

610

611

public <T> T deserializeComponent(byte[] data, Class<T> type) {

612

return serializationPlan.deserialize(data, type);

613

}

614

615

// Hybrid operations combining multiple strategies

616

public StorageEntry createStorageEntry(String key, Object data, StorageOptions options) {

617

byte[] serializedData;

618

619

if (options.isEncrypted()) {

620

if (data instanceof Serializable serializable) {

621

serializedData = toEncryptedBinary(serializable);

622

} else {

623

// Convert to JSON first, then encrypt

624

String json = toJson(data);

625

serializedData = toEncryptedBinary(json);

626

}

627

} else if (options.useComponentSerialization()) {

628

serializedData = serializeComponent(data);

629

} else if (options.isJsonFormat()) {

630

String json = toJson(data);

631

serializedData = json.getBytes(StandardCharsets.UTF_8);

632

} else {

633

if (data instanceof Serializable serializable) {

634

serializedData = toBinary(serializable);

635

} else {

636

throw new IllegalArgumentException("Object must be Serializable for binary format");

637

}

638

}

639

640

return new StorageEntry(key, serializedData, options);

641

}

642

643

public <T> T retrieveFromStorageEntry(StorageEntry entry, Class<T> type) {

644

StorageOptions options = entry.getOptions();

645

byte[] data = entry.getData();

646

647

if (options.isEncrypted()) {

648

if (String.class.equals(type)) {

649

String decrypted = fromEncryptedBinary(data, String.class);

650

return jacksonMapper.convertValue(decrypted, type);

651

} else {

652

return fromEncryptedBinary(data, type.asSubclass(Serializable.class));

653

}

654

} else if (options.useComponentSerialization()) {

655

return deserializeComponent(data, type);

656

} else if (options.isJsonFormat()) {

657

String json = new String(data, StandardCharsets.UTF_8);

658

return fromJson(json, type);

659

} else {

660

return fromBinary(data, type);

661

}

662

}

663

}

664

```

665

666

This serialization library provides comprehensive support for various serialization needs in CAS applications, from simple JSON conversion to encrypted binary storage with proper security and performance considerations.