Spring Boot Data Sanitization with One Annotation: Sanitizer-Lib Tutorial

This tutorial demonstrates how to use the open-source Sanitizer-Lib to automatically sanitize sensitive fields in Spring Boot 3.5 applications via the @Sanitize annotation, covering JSON deserialization, JPA persistence, built-in and custom sanitizers, and programmatic registry usage.

Spring Full-Stack Practical Cases
Spring Full-Stack Practical Cases
Spring Full-Stack Practical Cases
Spring Boot Data Sanitization with One Annotation: Sanitizer-Lib Tutorial

Introduction

In the context of stricter data compliance, Spring Boot interfaces returning sensitive data like phone numbers and ID cards risk leakage. Sanitizer-Lib is an enterprise-grade input sanitization framework for Java applications that integrates with Spring Boot and JPA. It ensures data integrity and consistency by automatically sanitizing fields on DTOs and entities before processing or persistence.

Core Capabilities

Annotations and API

@Sanitize(using = Class<? extends FieldSanitizer>[]) : Declarative annotation for field-level data sanitization.

FieldSanitizer<T> : Core interface for implementing custom sanitization logic.

Built-in Sanitizers

The library provides several built-in sanitizers (shown in the article's image), such as TrimSanitizer and HtmlEscapeSanitizer.

Framework Integration

Spring Boot (sanitizer-spring)

Jackson SanitizerModule for automatic cleanup during deserialization.

Spring-managed SanitizerRegistry for programmatic resolver access.

Zero-configuration setup via Spring Boot auto-configuration.

JPA (sanitizer-jpa)

SanitizationEntityListener automatically invoked at @PrePersist and @PreUpdate lifecycle events.

Seamless integration with existing entity models.

Practical Examples

2.1 Environment Setup

Environment: Spring Boot 3.5.0

Add the following Maven dependencies:

<dependency>
  <groupId>io.github.rabinarayanpatra.sanitizer</groupId>
  <artifactId>sanitizer-spring</artifactId>
  <version>1.1.0</version>
</dependency>
<dependency>
  <groupId>io.github.rabinarayanpatra.sanitizer</groupId>
  <artifactId>sanitizer-jpa</artifactId>
  <version>1.1.0</version>
</dependency>

Note: sanitizer-jpa is optional depending on use case.

2.2 JSON Deserialization

Define a POJO with @Sanitize annotations:

public class User {
  private Integer id;
  // Name: trim + filter HTML to prevent XSS
  @Sanitize(using = {TrimSanitizer.class, HtmlEscapeSanitizer.class})
  private String name;
  // Phone: trim only
  @Sanitize(using = {TrimSanitizer.class})
  private String phone;
  private String password;
  private Integer age;
  private String sex;
}

Define a controller endpoint:

@PostMapping
public User save(@RequestBody User user) {
  return this.userService.save(user);
}

When tested via Postman, the framework automatically processes data according to field rules. The database stores sanitized values (e.g., HTML tags escaped, whitespace trimmed).

2.3 Persisting Data with JPA

To sanitize during JPA persistence, include the sanitizer-jpa dependency and annotate the entity:

@Entity
@Table(name = "x_user")
@EntityListeners(SanitizationEntityListener.class)
public class User {
  @Sanitize(using = {TrimSanitizer.class, HtmlEscapeSanitizer.class})
  private String name;
  @Sanitize(using = {TrimSanitizer.class})
  private String phone;
  // ...
}

A test case demonstrates the behavior:

@Test
public void testSave() {
  User user = new User();
  user.setAge(40);
  user.setName("<script>王五</script>");
  user.setPassword("111111");
  user.setPhone("   1355555555 ");
  user.setSex("男");
  this.userService.save(user);
}

The result shows the name field has HTML escaped and phone trimmed in the database.

2.4 Configurable Sanitizers

Sanitizers can accept parameters via the params attribute. Extend ConfigurableFieldSanitizer to create parameterized sanitizers.

Example using built-in TruncateSanitizer:

@Sanitize(using = TruncateSanitizer.class, params = "maxLength=100,suffix=...")
private String description;

Custom configurable sanitizer example ( MaskSanitizer):

public class MaskSanitizer extends ConfigurableFieldSanitizer<String> {
  @Override
  public String sanitize(final String input) {
    if (input == null) return null;
    int reveal = getIntParam("reveal", 4);
    String ch = getParam("character", "*");
    if (input.length() <= reveal) return input;
    return ch.repeat(input.length() - reveal) + input.substring(input.length() - reveal);
  }
}

Usage:

@Sanitize(using = MaskSanitizer.class, params = "reveal=6,character=X")

2.5 Custom Sanitizers

Implement FieldSanitizer directly for simple custom logic:

@Component
public class NumericOnlySanitizer implements FieldSanitizer<String> {
  @Override
  public String sanitize(final String input) {
    return input == null ? null : input.replaceAll("[^0-9]", "");
  }
}

Programmatic Usage

For manual sanitization, inject SanitizerRegistry:

private final SanitizerRegistry registry;

public String processInput(String input) {
  return registry.get(XxxSanitizer.class).sanitize(input);
}
Original Source

Signed-in readers can open the original source through BestHub's protected redirect.

Sign in to view source
Republication Notice

This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactadmin@besthub.devand we will review it promptly.

JavaSpring BootOpen SourceSecurityAnnotationJPAData SanitizationSanitizer-Lib
Spring Full-Stack Practical Cases
Written by

Spring Full-Stack Practical Cases

Full-stack Java development with Vue 2/3 front-end suite; hands-on examples and source code analysis for Spring, Spring Boot 2/3, and Spring Cloud.

0 followers
Reader feedback

How this landed with the community

Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.