能否将Spring配置属性用于javax.validation注解参数?
无需自定义验证约束的解决方案
针对你在Spring Boot中想用配置属性替代javax.validation注解里魔法数字的需求,有两种简便方案可以不用编写自定义验证约束:
方案1:方法级验证结合SpEL(最省心)
Spring的方法级验证(通过@Validated注解开启)支持在验证注解的参数中使用SpEL表达式,能直接引用配置属性或类中注入的属性:
方式A:直接在注解里引用配置属性
import org.springframework.validation.annotation.Validated; import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.RequestBody; import org.springframework.web.bind.annotation.RestController; import javax.validation.constraints.Size; @RestController @Validated public class AccountController { @PostMapping("/accounts") public void createAccount( @RequestBody @Size(max = "#{environment.getProperty('myApp.accounts.maxNameLength', T(Integer))}") String name ) { // 业务逻辑实现 } }
方式B:先注入配置属性再引用
如果需要在多个地方复用这个值,先把配置注入到类中,再通过SpEL引用:
import org.springframework.beans.factory.annotation.Value; import org.springframework.validation.annotation.Validated; import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.RequestBody; import org.springframework.web.bind.annotation.RestController; import javax.validation.constraints.Size; @RestController @Validated public class AccountController { @Value("${myApp.accounts.maxNameLength}") private int maxNameLength; @PostMapping("/accounts") public void createAccount( @RequestBody @Size(max = "#{maxNameLength}") String name ) { // 业务逻辑实现 } }
这种方案完全依托Spring原生特性,不用额外写验证代码,适合在Controller或Service的方法参数上做验证。
方案2:DTO类上用@ScriptAssert结合配置Bean
如果必须在DTO类层面做验证,可以用Hibernate Validator提供的@ScriptAssert注解,通过SpEL引用配置Bean的属性:
- 先定义配置属性类,绑定yaml中的配置:
import org.springframework.boot.context.properties.ConfigurationProperties; import org.springframework.stereotype.Component; @Component @ConfigurationProperties(prefix = "myApp.accounts") public class AccountProperties { private int maxNameLength; // getter和setter public int getMaxNameLength() { return maxNameLength; } public void setMaxNameLength(int maxNameLength) { this.maxNameLength = maxNameLength; } }
- 在DTO类上添加
@ScriptAssert注解:
import javax.validation.constraints.NotNull; import org.hibernate.validator.constraints.ScriptAssert; @ScriptAssert( lang = "spel", script = "_this.name == null || _this.name.length() <= @accountProperties.maxNameLength", message = "name长度不能超过{0}", params = {"@accountProperties.maxNameLength"} ) public class AccountDTO { @NotNull private String name; // getter和setter }
这里的@accountProperties是Spring容器中配置Bean的默认名称(类名首字母小写),SpEL会自动解析并获取配置值作为验证上限。
内容的提问来源于stack exchange,提问作者E-Riz
相关产品推荐
相关产品推荐

