Java @第二次调用类方法时,值字段显示为null
在我的自定义注释中,我将使用允许邮件使用的域Java @第二次调用类方法时,值字段显示为null,java,spring-boot,spring-properties,Java,Spring Boot,Spring Properties,在我的自定义注释中,我将使用允许邮件使用的域 @Documented @Constraint(validatedBy = ValidEmail.CheckIfValidMail.class) //@Constraint(validatedBy = {}) @Target({ METHOD, FIELD, ANNOTATION_TYPE, CONSTRUCTOR, PARAMETER, TYPE_USE }) //@Repeatable(List.class) @Retention(RUNTIME
@Documented
@Constraint(validatedBy = ValidEmail.CheckIfValidMail.class)
//@Constraint(validatedBy = {})
@Target({ METHOD, FIELD, ANNOTATION_TYPE, CONSTRUCTOR, PARAMETER, TYPE_USE })
//@Repeatable(List.class)
@Retention(RUNTIME)
@Component
public @interface ValidEmail {
String message() default "Invalid String !!";
Class<?>[] groups() default {};
Class<? extends Payload>[] payload() default {};
@Target({ METHOD, FIELD, ANNOTATION_TYPE, CONSTRUCTOR, PARAMETER, TYPE_USE })
@Retention(RUNTIME)
@Documented
@interface List {
ValidEmail[] value();
}
@Component
public class CheckIfValidMail implements ConstraintValidator<ValidEmail, String> {
@Autowired
UserServiceImplOld userServiceImpl;
// @Value("${app.mail.allowedDomains:gmail}")
private String[] allowedDomainsForMail;
@Value("${app.mail.allowedDomains:gmail}")
public void setAllowedDomainsForMail(String[] allowedDomainsForMail) {
this.allowedDomainsForMail = allowedDomainsForMail;
}
// private String[] allowedDomainsForMail = new String[] { "gmail", "rediffmail", "yahoo" };
protected String message;
@Override
public void initialize(ValidEmail validEmail) {
this.message = validEmail.message() + " Allowed Domain(s): " + Arrays.toString(allowedDomainsForMail);
}
@Override
public boolean isValid(String value, ConstraintValidatorContext context) {
if (value == null)
return true;
String allowedDomainRegEx = String.join("|", allowedDomainsForMail);
String mailRegex = "^(?i)[A-Za-z0-9+_.-]+@(?:" + allowedDomainRegEx + ")\\.(?:.*)$";
context.disableDefaultConstraintViolation();
context.buildConstraintViolationWithTemplate(message).addConstraintViolation();
return value.matches(emailRegex);
}
}
}
实施中
UserDto addUserDto = new UserDto();
addUserDto.setEmailId("satish");
addUserDto.setisLoginAllowed(false);
ValidatorFactory factory = Validation.buildDefaultValidatorFactory();
Validator validator = factory.getValidator();
System.out.println("Validating :-\n" + validator.validate(addUserDto));
因此,当验证它时,会转到ValidMail接口,allowedMailDomains值为null,以注入属性allowedMailDomains,您的类CheckIfValidMail必须是一个bean。因此,如果向类中添加@Component注释(例如),问题将得到解决。尝试注册
localvalidatoryBean
并使用它,而不是Validation.buildDefaultValidatoryFactory()
LocalValidatoryFactoryBean
应该允许您在验证器中获得依赖注入好处
UPD:
默认情况下,LocalValidatoryBean配置使用Spring创建ConstraintValidator实例的SpringConstraintValidatorFactory。这让您的自定义ConstraintValidator像其他Springbean一样从依赖项注入中受益
然后在您的实现类中自动连接此bean:
@Autowired
private ValidatorFactory validatorFactory;
并使用它而不是DefaultValidatorFactory
:
Validator validator = validatorFactory.getValidator();
validator.validate(addUserDto);
问题是:
- 在
API中运行代码时,您是在一个Spring容器中运行的,该容器将REST
初始化为CheckIfValidMail
,然后它将从组件
容器中获取所需的所有值和所有内容Spring
- 当您以编程方式初始化它时,它没有初始化为
,也没有组件
来获取容器
,我甚至怀疑在第二种情况下是否加载了@值
(我看不到整个代码,所以我不确定)属性
private String[]允许邮件域;
@值(${poss.mail.allowedDomains:gmail}”)
public void setAllowedMailDomains(字符串[]allowedMailDomains){
this.allowedMailDomains=allowedMailDomains;
}
然后在编程验证中设置该值,这样就可以工作了
否则,只需在容器中对其进行初始化,就可以修复它。当您获得空值时,请共享代码?@dassum在创建dto对象时添加了代码,并且存在ValidEmail批注there@Component如何创建接口注释?从我调用它的地方,它已经有了组件和服务,但是在ValidMail接口中,我仍然得到了null。我将它与@Component annoation一起交给接口中的类,仍然得到null。该类(实现)应该是一个bean。事实上,您需要注入它的属性。如果不是bean,Spring容器如何注入该值?CheckIfValidMail是一个内部类?我不明白它是如何在一个界面内?你能解释一下吗。@zouari编辑你的答案,这样我就可以删除我的反对票,你是对的,我会在我的答案中解释。添加了完整的代码。在setter中尝试了@Value。仍然是空的。如何分配容器?有什么有用的链接吗?
@Autowired
private ValidatorFactory validatorFactory;
Validator validator = validatorFactory.getValidator();
validator.validate(addUserDto);