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.
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);
}Signed-in readers can open the original source through BestHub's protected redirect.
This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactand we will review it promptly.
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.
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.
