SpEL Validator Documentation

website·Indexed 31 days ago

https://spel-validator.sticki.cn

A parameter validation package based on Spring Expression Language (SpEL) and an extension of jakarta.validation-api. It simplifies complex parameter validation scenarios by allowing the use of SpEL expressions and integration with Spring Beans. Features include custom constraint annotations, i18n support since v0.5.0-beta, and an IntelliJ IDEA plugin for intelligent development support.

Tokens
8.6K
Snippets
39
Records
52
Agent score
56%

What's inside SpEL Validator

  1. Overview of SpEL Validator

    SpEL Validator is a parameter validation package based on Spring Expression Language (SpEL) and serves as an extension to jakarta.validation-api. It is designed to simplify parameter validation, particularly for scenarios where a field's validation depends on the value of another field. It is intended to complement, not replace, standard jakarta.validation-api annotations.
  2. Overview of spel-validator features

    spel-validator is a validation library that extends jakarta.validation-api to provide flexible validation logic using Spring Expression Language (SpEL). Key capabilities include:

    • SpEL Integration: Allows complex validation logic and direct calls to injected Spring Beans within validation rules.
    • Context Awareness: Supports cross-field logic validation by operating within the context of the entire object.
    • Seamless Integration: Extends the standard Jakarta Validation API without modifying existing behavior, allowing it to be added to existing projects easily.
    • Customization: Supports the creation of custom constraint annotations for business-specific validation rules.
    • IDE Support: An IntelliJ IDEA plugin is available providing SpEL syntax highlighting, intelligent completion, navigation, refactoring, and error checking.
  3. Understand the SpEL Validator execution workflow

    The SpEL Validator extends the Jakarta Validation framework to allow flexible field validation using SpEL expressions. It integrates with Spring MVC's native validation mechanism. For the validation to trigger, a class must be annotated with @SpelValid and the method parameter must be annotated with @Valid or @Validated.

    Execution Flow:

    1. @Valid/@Validated triggers the standard Java validation mechanism.
    2. The framework detects the @SpelValid annotation on the class, which activates the SpelValidator.
    3. SpelValidator#isValid() is called, which invokes the SpelValidExecutor.
    4. SpelValidExecutor scans the class fields for @SpelConstraint annotations (e.g., @SpelSize, @SpelNotNull, @SpelFuture).
    5. The executor evaluates the condition and group settings to determine if the specific constraint should run.
    6. The corresponding SpelConstraintValidator executes the validation logic.
    7. Errors are collected as FieldError objects and converted into standard ConstraintViolation objects, allowing them to be handled by Spring's BindingResult or returned as 400 Bad Request responses.
    @Valid/@Validated
       ↓
    @SpelValid                <- Activates SpelValidator
       ↓
    SpelValidator#isValid()   <- Calls SpelValidExecutor
       ↓
    SpelValidExecutor         <- Scans fields, parses expressions, calls constraint validators
       ↓
    SpelConstraintValidator   <- Executes constraint validation
       ↓
    FieldError                <- Collects error information
       ↓
    ConstraintViolation       <- Converts to standard validation framework structure
  4. Use SpEL Validator Support plugin features

    The plugin provides several intelligent features when using SpEL Validator annotations:

    • Language Injection: Automatic syntax highlighting and basic SpEL completion (e.g., @beanName, T(ClassName)).
    • Smart Field Completion: Typing #this. triggers completion for current class fields (including private), inherited fields, and nested fields (e.g., #this.user.address.city) with type information.
    • Navigation: Use Ctrl+Click to jump to field definitions or use 'Find Usages' to locate all references of a field within SpEL expressions.
    • Refactoring: Automatically updates SpEL expression references when a field is renamed.
    • Error Checking: Real-time validation of field references with warnings and hover-over error messages for non-existent fields.
    @Data
    public class UserDto {
        private String userName;
        private Integer age;
        private Address address;
        
        // Typing #this. here will suggest userName, age, address
        @SpelNotNull(condition = "#this.age != null")
        private String userNameCheck;
        
        // Supports nested completion: #this.address. will suggest Address class fields
        @SpelAssert(assertTrue = "#this.address.city != null")
        private String addressCheck;
    }
    
    @Data
    public class Address {
        private String city;
        private String street;
    }
  5. Configure internationalized validation messages in SpEL Validator

    SpEL Validator (v0.5.0-beta+) supports i18n for validation messages. You can provide default messages for built-in constraints or override them by creating .properties files in the resources directory. Use the following naming convention for locale-specific files:

    • ValidationMessages.properties (Default)
    • ValidationMessages_zh_CN.properties (Simplified Chinese)
    • ValidationMessages_en_US.properties (US English)

    Messages are defined as key-value pairs. To use a specific key in a constraint annotation, wrap the key in curly braces {} within the message attribute.

    you.message.key.SpelNotNull=must not be null
    @SpelNotNull(assertTrue = "true", message = "{you.message.key.SpelNotNull}")
    private Integer age;
  6. Migrate from spel-validator v0.6.x to v0.7.0

    Upgrading to v0.7.0 introduces several breaking changes to the API. Developers must update the following references:

    1. Replace the ObjectValidResult.EMPTY constant with the ObjectValidResult.empty() factory method to avoid global state pollution.
    2. Update NumberComparatorUtil usage: constants LESS_THAN, GREATER_THAN, and FINITE_VALUE have changed from OptionalInt to the CompareResult enum. The treatNanAs parameter in the compare() method has also been updated to use CompareResult.
    3. Rename calls to SpelNotSupportedTypeException.getSupperType() to getSupportedType().
  7. Install SpEL Validator Support plugin for IntelliJ IDEA

    The SpEL Validator Support plugin provides intelligent development support for the SpEL Validator framework. It requires IntelliJ IDEA 2023.2 or higher and the Spring plugin (enabled by default) for full SpEL language support.

    Installation Methods:

    1. JetBrains Marketplace (Recommended): Go to Settings/Preferences → Plugins, search for "SpEL Validator Support", click Install, and restart IDEA.
    2. Manual Installation: Download the latest ZIP from the GitHub Releases page. Go to Settings/Preferences → Plugins, click the gear icon → Install Plugin from Disk, select the ZIP, and restart IDEA.
  8. Enable SpEL constraint validation

    To activate spel-validator constraints (like @SpelNotNull), two conditions must be met:

    1. The method parameter in the Controller must be annotated with @Valid or @Validated.
    2. The target entity class must be annotated with @SpelValid.

    If only @Valid/@Validated is present, only standard jakarta.validation annotations (e.g., @NotNull) will work. If only @SpelValid is present, no validation will occur because @SpelValid itself is a constraint that requires a validator trigger.

    @RestController
    @RequestMapping("/example")
    public class ExampleController {
    
      @PostMapping("/simple")
      public Resp<Void> simple(@RequestBody @Valid SimpleExampleParamVo simpleExampleParamVo) {
        return Resp.ok(null);
      }
    }
    
    @Data
    @SpelValid
    public class SimpleExampleParamVo {
      @SpelNotNull(message = "Content cannot be null")
      private String content;
    }
  9. Trigger SpEL validation in Spring controllers

    To enable SpEL validation, you must use a combination of the standard Jakarta/Spring validation trigger and the SpEL-specific class annotation. If only one is present, the SpEL logic will not execute.
    // 1. Annotate the DTO class with @SpelValid
    @SpelValid
    public class MyParam {
        // fields with @SpelConstraint annotations
    }
    
    // 2. Annotate the controller parameter with @Valid or @Validated
    @PostMapping("/submit")
    public Resp<Void> doSomething(@RequestBody @Valid MyParam param) {
        ...
    }
  10. Install spel-validator

    Choose the dependency based on your project's JDK and Spring Boot version. Use spel-validator-javax for Spring Boot 2.x (JDK 8+) and spel-validator-jakarta for Spring Boot 3.x (JDK 11+).
    <!-- For Spring Boot 2.x / JDK 8+ -->
    <dependency>
      <groupId>cn.sticki</groupId>
      <artifactId>spel-validator-javax</artifactId>
      <version>Latest Version</version>
    </dependency>
    
    <!-- For Spring Boot 3.x / JDK 11+ -->
    <dependency>
      <groupId>cn.sticki</groupId>
      <artifactId>spel-validator-jakarta</artifactId>
      <version>Latest Version</version>
    </dependency>
  11. Configure SpEL validation in DTOs and Controllers

    To enable SpEL validation, follow these three steps:

    1. Annotate the target DTO class with @SpelValid to enable validation for that entity.
    2. Use constraint annotations like @SpelNotNull on specific fields. The condition attribute accepts a SpEL expression (e.g., #this.fieldName == value) to determine when the constraint should be applied.
    3. In the Controller, use @Valid or @Validated on the request body parameter to trigger the validation process.
    @Data
    @SpelValid // Enable validation for this class
    public class SimpleExampleParamVo {
      @NotNull
      private Boolean switchAudio;
    
      // audioContent must not be null if switchAudio is true
      @SpelNotNull(condition = "#this.switchAudio == true", message = "语音内容不能为空")
      private Object audioContent;
    }
    
    @RestController
    @RequestMapping("/example")
    public class ExampleController {
      @PostMapping("/simple")
      public Resp<Void> simple(@RequestBody @Valid SimpleExampleParamVo simpleExampleParamVo) {
        return Resp.ok(null);
      }
    }
  12. Call Spring Beans in SpEL validation expressions

    Once Spring Bean support is enabled, you can invoke methods on Spring-managed beans within SpEL expressions using the syntax @beanName.methodName(arguments). This allows validation logic to depend on service-layer data (e.g., checking if a record exists in a database).
    @Data
    @SpelValid
    public class SimpleExampleParamVo {
    
      /**
       * Call userService.getById to verify if the user exists
       */
      @SpelAssert(assertTrue = "@userService.getById(#this.userId) != null", message = "用户不存在")
      private Long userId;
    }