Class ApiResponseAutoConfiguration

java.lang.Object
io.github.og4dev.config.ApiResponseAutoConfiguration

@Configuration public class ApiResponseAutoConfiguration extends Object
Autoconfiguration class for the OG4Dev Spring API Response Library.

This configuration is automatically loaded by Spring Boot's autoconfiguration mechanism when the library is present on the classpath. It registers essential beans required for the library to function properly, including the comprehensive global exception handler.

Zero Configuration Required: Simply adding the library dependency enables all features automatically. No manual @ComponentScan or @Import annotations are needed.

What Gets Auto-Configured:

  • GlobalExceptionHandler - Comprehensive exception handling with RFC 9457 ProblemDetail format
    • 10 built-in exception handlers covering all common error scenarios
    • Automatic trace ID generation and logging
    • Validation error aggregation and formatting
    • Production-ready error messages

How It Works:

Spring Boot 3.x+ automatically reads META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports and loads this configuration class during application startup.

Disabling Auto-Configuration:

If you need to customize or disable this autoconfiguration, you can exclude it in your main application class:


 @SpringBootApplication(exclude = ApiResponseAutoConfiguration.class)
 public class Application {
     public static void main(String[] args) {
         SpringApplication.run(Application.class, args);
     }
 }
 

Or in application.properties:

 spring.autoconfigure.exclude=io.github.og4dev.config.ApiResponseAutoConfiguration
 

Alternatively, disable the exception handler while keeping other library features:

 api-response.enabled=false
 
Since:
1.0.0
Version:
1.2.0
Author:
Pasindu OG
See Also:
  • Constructor Details

    • ApiResponseAutoConfiguration

      public ApiResponseAutoConfiguration()
      Default constructor for ApiResponseAutoConfiguration.

      This constructor is automatically invoked by Spring's dependency injection container during application startup when autoconfiguration is enabled.

  • Method Details

    • apiResponseAdvisor

      @Bean public GlobalExceptionHandler apiResponseAdvisor()
      Registers the GlobalExceptionHandler as a Spring bean for automatic exception handling.

      The handler provides comprehensive centralized exception management using Spring's RestControllerAdvice mechanism, automatically converting 10 different types of exceptions to RFC 9457 ProblemDetail responses.

      Exception Coverage:

      • General exceptions (500 Internal Server Error)
      • Validation errors with field-level details (400 Bad Request)
      • Type mismatch errors (400 Bad Request)
      • Malformed JSON requests (400 Bad Request)
      • Missing required parameters (400 Bad Request)
      • 404 Not Found errors
      • 405 Method Not Allowed
      • 415 Unsupported Media Type
      • Null pointer exceptions (500 Internal Server Error)
      • Custom ApiException instances (custom status codes)

      Features:

      • Automatic trace ID generation for all errors
      • Consistent trace IDs between logs and responses
      • RFC 9457 compliant error format
      • Comprehensive SLF4J logging with appropriate severity levels
      • Automatic timestamp inclusion in all error responses
      Returns:
      A new instance of GlobalExceptionHandler registered as a Spring bean.
    • strictJsonCustomizer

      @Bean public org.springframework.boot.jackson.autoconfigure.JsonMapperBuilderCustomizer strictJsonCustomizer()
      Configures strict JSON deserialization with comprehensive security features and flexible string handling.

      This bean customizer enhances Jackson's JSON processing with production-ready security and data quality features that are automatically applied to all API endpoints without requiring any code changes. All features work seamlessly with Spring Boot 3.x and 4.x autoconfiguration.

      Overview of Features

      This configuration provides four critical layers of protection and data processing:

      1. Strict Property Validation - Prevents mass assignment attacks
      2. Case-Insensitive Enum Handling - Improves API usability
      3. Automatic XSS Prevention - Blocks HTML/XML injection attacks
      4. Smart String Trimming - Removes whitespace with opt-out capability

      Feature 1: Strict Property Validation

      Enables DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES to reject JSON payloads containing unexpected fields. This prevents three critical security issues:

      • Mass Assignment Vulnerabilities: Attackers cannot inject fields like isAdmin: true
      • Data Injection Attacks: Prevents modification of unintended database fields
      • Client Errors: Detects typos early, preventing silent data loss

      Example:

      
       // DTO Definition
       public class UserDTO {
           private String name;
           private String email;
       }
      
       // Valid Request
       {"name": "John", "email": "[email protected]"}  // ✓ Success
      
       // Invalid Request (will be rejected with 400 Bad Request)
       {"name": "John", "email": "[email protected]", "isAdmin": true}  // ✗ Unknown field
       

      Feature 2: Case-Insensitive Enum Handling

      Enables MapperFeature.ACCEPT_CASE_INSENSITIVE_ENUMS for flexible enum deserialization. Clients can send enum values in any case format, improving API usability without compromising type safety or security.

      Example:

      
       public enum Status { ACTIVE, INACTIVE, PENDING }
      
       // All these are accepted and map to Status.ACTIVE:
       {"status": "ACTIVE"}   // ✓ Original
       {"status": "active"}   // ✓ Lowercase
       {"status": "Active"}   // ✓ Title case
       {"status": "AcTiVe"}   // ✓ Mixed case
       

      Feature 3: Automatic XSS Prevention

      Registers a custom StdScalarDeserializer (AdvancedStringDeserializer) that performs automatic HTML/XML tag detection and rejection at the deserialization layer. This provides fail-fast security that prevents malicious content from ever entering your system.

      Detection Mechanism:

      • Uses regex pattern: (?s).*<\s*[a-zA-Z/!].*
      • Detects opening tags: <script>, <img>, <div>
      • Detects closing tags: </div>, </script>
      • Detects special tags: <!DOCTYPE>, <!--comment-->
      • Works across multiple lines (DOTALL mode enabled)

      Security Advantage: Unlike HTML escaping (which transforms < to &lt;), this approach rejects the request entirely. This prevents:

      • Stored XSS attacks
      • DOM-based XSS attacks
      • Second-order injection vulnerabilities
      • Encoding bypass attempts

      Example:

      
       // Valid Requests
       {"comment": "Hello World"}                     // ✓ Plain text
       {"comment": "Price: $100 < $200"}              // ✓ Comparison operators (no tag)
       {"comment": "2 + 2 = 4"}                       // ✓ Math expressions
      
       // Invalid Requests (throws IllegalArgumentException)
       {"comment": "<script>alert('XSS')</script>"}   // ✗ Script injection
       {"comment": "<img src=x onerror=alert(1)>"}    // ✗ Image XSS
       {"comment": "Hello<br>World"}                  // ✗ HTML tags
       {"comment": "<!--comment-->"}                  // ✗ HTML comments
       {"comment": "<!DOCTYPE html>"}                 // ✗ DOCTYPE declaration
       

      Feature 4: Smart String Trimming with @NoTrim Support

      Automatically removes leading and trailing whitespace from all string fields by default, improving data quality and preventing common user input errors. Fields can opt-out using the @NoTrim annotation when whitespace preservation is required.

      Default Trimming Behavior

      All string fields are automatically trimmed during deserialization:

      
       public class UserDTO {
           private String username;  // Auto-trimmed
           private String email;     // Auto-trimmed
       }
      
       // Input                            → Output
       {"username": "  john  "}            → {"username": "john"}
       {"email": " [email protected]   "}   → {"email": "[email protected]"}
       {"username": "\n\tjohn\t\n"}        → {"username": "john"}
       

      Opt-Out with @NoTrim Annotation

      The AdvancedStringDeserializer implements context-aware deserialization using ValueDeserializer.createContextual(DeserializationContext, BeanProperty). When it detects the @NoTrim annotation on a field, it creates a specialized deserializer instance with trimming disabled while maintaining XSS validation.

      Use Cases for @NoTrim:

      • Password Fields: Users may intentionally include spaces in passwords
      • Code Snippets: Programming code requiring exact indentation
      • Base64 Data: Encoded strings that must not be modified
      • Pre-formatted Text: Poetry, ASCII art, or formatted documents
      • API Keys/Tokens: Credentials that must be processed exactly as provided

      Example:

      
       import io.github.og4dev.annotation.NoTrim;
      
       public class LoginDTO {
           private String username;       // Trimmed: "  admin  " → "admin"
      
           @NoTrim
           private String password;       // NOT trimmed: "  pass123  " → "  pass123  "
       }
      
       public class CodeSubmissionDTO {
           private String title;          // Trimmed
      
           @NoTrim
           private String sourceCode;     // NOT trimmed: preserves indentation
       }
       

      Important: XSS Validation Always Active

      Even when @NoTrim is used, HTML tag detection is still performed for security. This ensures that opting out of trimming does not create security vulnerabilities.

      
       public class SecureDTO {
           @NoTrim
           private String sensitiveData;
       }
      
       // These will STILL be rejected even with @NoTrim:
       {"sensitiveData": "  <script>alert(1)</script>  "}  // ✗ XSS attempt blocked
       {"sensitiveData": "  <img src=x>  "}               // ✗ HTML tag blocked
       

      Implementation Details

      This method registers an inner class AdvancedStringDeserializer that extends StdScalarDeserializer<String>. The deserializer has two modes:

      • Default Mode: shouldTrim = true - Trims and validates strings
      • NoTrim Mode: shouldTrim = false - Only validates (no trimming)

      The createContextual() method inspects each field's annotations during deserialization context creation. If @NoTrim is found, it returns a new instance configured for no-trim mode.

      Global Application Scope

      As a JsonMapperBuilderCustomizer bean, these settings are automatically applied to Spring Boot's default ObjectMapper, affecting:

      • All @RequestBody deserialization in REST controllers
      • All @ResponseBody serialization
      • WebSocket message handling
      • Spring Data REST endpoints
      • Spring Cloud Feign clients
      • Any component using the autoconfigured ObjectMapper

      Null Value Handling

      Null values are preserved and never converted to empty strings:

      
       {"name": null}      → name = null (not "")
       {"name": ""}        → name = ""
       {"name": "  "}      → name = ""   (trimmed to empty)
       

      Disabling These Features

      If you need to accept HTML content or disable any of these features, you have three options:

      1. Exclude Auto-Configuration:
        
         @SpringBootApplication(exclude = ApiResponseAutoConfiguration.class)
         public class Application { }
             
      2. Override with @Primary Bean:
        
         @Configuration
         public class CustomConfig {
             @Bean
             @Primary
             public JsonMapperBuilderCustomizer myCustomizer() {
                 return builder -> {
                     // Your custom configuration
                 };
             }
         }
             
      3. Use Application Properties:
         spring.autoconfigure.exclude=io.github.og4dev.config.ApiResponseAutoConfiguration
             

      Performance Considerations

      The regex validation is highly optimized and adds negligible overhead (typically <1ms per request). The contextual deserializer is created once per field during mapper initialization, not on every request, ensuring optimal runtime performance.

      Returns:
      A JsonMapperBuilderCustomizer that configures strict JSON processing with automatic string validation, context-aware trimming, HTML tag rejection, unknown property rejection, and case-insensitive enum handling.
      Since:
      1.1.0
      See Also:
      • DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES
      • MapperFeature.ACCEPT_CASE_INSENSITIVE_ENUMS
      • NoTrim
      • JsonMapperBuilderCustomizer
      • StdScalarDeserializer
      • ValueDeserializer.createContextual(DeserializationContext, BeanProperty)