You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用Hibernate动态模型(无实体类)时如何通过Hibernate Validator验证HTTP请求

Validating Map<String, Object> Request Body with @Valid in Hibernate Dynamic Model

Got it, since you're building CRUD with Hibernate's dynamic model and relying on Map<String, Object> instead of traditional entities/DTOs, the standard @Valid annotation won't work out of the box—it’s designed for JavaBeans with getter/setter methods, not generic maps. Here are three actionable ways to add validation to your /signup endpoint:

1. Custom Validation Annotation + Validator

Create a custom annotation that targets Map, then implement a validator to check the map's key-value pairs against your rules (like email format, password length, required fields).

Step 1: Define the Custom Annotation

@Target({ElementType.PARAMETER, ElementType.FIELD})
@Retention(RetentionPolicy.RUNTIME)
@Constraint(validatedBy = UserMapValidator.class)
public @interface ValidUserMap {
    String message() default "Invalid user data";
    Class<?>[] groups() default {};
    Class<? extends Payload>[] payload() default {};
}

Step 2: Implement the Validator

public class UserMapValidator implements ConstraintValidator<ValidUserMap, Map<String, Object>> {

    private Validator validator;

    @Override
    public void initialize(ValidUserMap constraintAnnotation) {
        ValidatorFactory factory = Validation.buildDefaultValidatorFactory();
        validator = factory.getValidator();
    }

    @Override
    public boolean isValid(Map<String, Object> userMap, ConstraintValidatorContext context) {
        boolean isValid = true;

        // Validate required fields exist
        if (userMap.get("email") == null || userMap.get("password") == null) {
            context.buildConstraintViolationWithTemplate("Email and password are required")
                   .addConstraintViolation();
            isValid = false;
        } else {
            // Validate email format
            String email = userMap.get("email").toString();
            Set<ConstraintViolation<String>> emailViolations = validator.validate(email, Email.class);
            if (!emailViolations.isEmpty()) {
                context.buildConstraintViolationWithTemplate("Invalid email format")
                       .addConstraintViolation();
                isValid = false;
            }

            // Validate password length
            String password = userMap.get("password").toString();
            if (password.length() < 8) {
                context.buildConstraintViolationWithTemplate("Password must be at least 8 characters")
                       .addConstraintViolation();
                isValid = false;
            }
        }

        // Add more validation rules as needed (username, phone, etc.)
        return isValid;
    }
}

Step 3: Apply the Annotation to Your Endpoint

First, add @Validated to your controller class (to enable Spring's method-level validation), then use your custom annotation on the Map parameter:

@RestController
@Validated // Required for custom parameter validation
public class UserController {

    @PostMapping("/signup")
    public ResponseEntity<RestResponse> signup(@ValidUserMap @RequestBody Map<String, Object> user) {
        var restResponse = new RestResponse<>();
        restResponse.setStatusCode(HttpStatus.OK.value());
        restResponse.setResponse(user);
        return ResponseEntity.status(HttpStatus.OK)
               .body(restResponse);
    }
}

2. Manual Validation with Java Bean Validator

If you don't want to create a custom annotation, you can directly inject the Validator into your controller and manually validate each field in the map:

@RestController
public class UserController {

    private final Validator validator;

    // Inject Validator via constructor
    public UserController(Validator validator) {
        this.validator = validator;
    }

    @PostMapping("/signup")
    public ResponseEntity<RestResponse> signup(@RequestBody Map<String, Object> user) {
        var restResponse = new RestResponse<>();
        Set<String> errors = new HashSet<>();

        // Check required fields
        if (user.get("email") == null) {
            errors.add("Email is required");
        } else {
            // Validate email format
            String email = user.get("email").toString();
            Set<ConstraintViolation<String>> violations = validator.validate(email, Email.class);
            violations.forEach(v -> errors.add(v.getMessage()));
        }

        if (user.get("password") == null) {
            errors.add("Password is required");
        } else {
            String password = user.get("password").toString();
            if (password.length() < 8) {
                errors.add("Password must be at least 8 characters");
            }
        }

        // Return errors if any, else proceed
        if (!errors.isEmpty()) {
            restResponse.setStatusCode(HttpStatus.BAD_REQUEST.value());
            restResponse.setErrors(errors);
            return ResponseEntity.status(HttpStatus.BAD_REQUEST).body(restResponse);
        }

        restResponse.setStatusCode(HttpStatus.OK.value());
        restResponse.setResponse(user);
        return ResponseEntity.status(HttpStatus.OK).body(restResponse);
    }
}

3. Use Hibernate Validator's Dynamic Bean Validation

Hibernate Validator allows validating dynamic objects using ValueExtractor and Validator.forExecutables(), though this is more advanced. You can define constraints for specific map keys without writing custom validators for each use case:

// Example of validating a map entry with @Email
ValueExtractor<Map<?, ?>> mapValueExtractor = new ValueExtractor<>() {
    @Override
    public void extractValues(Map<?, ?> originalValue, ValueExtractor.ValueReceiver receiver) {
        receiver.value(null, originalValue.get("email"));
    }
};

Validator validator = Validation.byProvider(HibernateValidator.class)
        .configure()
        .addValueExtractor(mapValueExtractor)
        .buildValidatorFactory()
        .getValidator();

Set<ConstraintViolation<Map<String, Object>>> violations = validator.validate(user);
// Handle violations by adding error messages to your response

内容的提问来源于stack exchange,提问作者Noman ali abbasi

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.30 15:02:37