使用JAX-RS时,是否可以将变量输入到自定义ConstraintValidator中? [英] Is there a way to get a variable in to a custom ConstraintValidator when using JAX-RS?
问题描述
在反序列化JSON有效负载时,我想使用自定义验证器来验证电话号码.该验证器需要知道客户所在的国家/地区才能正确解析电话号码.我可以在http标头中接受的国家/地区找到语言.
When de-serializing a JSON payload i want to validate a phone number using a custom validator. This validator needs to know what country the customer is in to correctly parse the phone number. The country i can find in the http header Accept-Language.
问题是如何为自定义验证器提供这些额外的元数据?
The problem is how can i provide the custom validator with this extra meta data?
我确定@Context会将HttpHeaders注入到PhoneNumberValidator中,但这不起作用:
I was sure that @Context would inject the HttpHeaders into the PhoneNumberValidator but this does not work:
@Context
private HttpHeaders mHttpHeaders;
该字段为空.
API端点:
@Path("customer")
public class CustomerResource {
@POST
@Consumes(MediaType.APPLICATION_JSON)
public Response postCustomer(@Valid Customer pCustomer) {
return Response.ok(pCustomer).build();
}
}
POJO:
@Getter
@Setter
public class Customer {
@NotNull
private String firstName;
@ValidPhoneNumber
private String mobileNumber;
}
Validator界面:
Validator interface:
@Documented
@Retention(RUNTIME)
@Target({ TYPE, FIELD })
@Constraint(validatedBy = { PhoneNumberValidator.class })
public @interface ValidPhoneNumber {
String message() default "Phone number is not valid!";
Class<?>[] groups() default {};
Class<? extends Payload>[] payload() default {};
}
自定义验证器:
@Slf4j
public class PhoneNumberValidator implements ConstraintValidator<ValidPhoneNumber, String> {
@Override
public boolean isValid(String vTelephone, ConstraintValidatorContext pContext) {
final PhoneNumberUtil vPhoneNumberUtil = PhoneNumberUtil.getInstance();
// TODO: Get the country in here somehow
final String vCountry = "GB";
try {
PhoneNumber vPhoneNumber = vPhoneNumberUtil.parse(vTelephone, vCountry);
if (!vPhoneNumberUtil.isValidNumber(vPhoneNumber)) {
log.error("Invalid {} phone number: {}", vCountry, vTelephone);
return false;
}
} catch (NumberParseException e) {
log.error("Error parsing {} as a phone number in {}: {}", vTelephone, vCountry, e.getMessage());
return false;
}
return true;
}
}
推荐答案
HttpHeaders
对象还不是CDI托管的bean-我之所以说是因为这是Jakarta的JAX-RS 3.0计划的一部分. CDI bean,但对于JAX-RS 2.1和更早版本,不是.
The HttpHeaders
object is not (yet) a CDI managed bean - I say yet because it is part of the plan for Jakarta's JAX-RS 3.0 to be a CDI bean, but for JAX-RS 2.1 and earlier, it is not.
但是资源类可能是CDI管理的bean.因此,您可以将HttpHeaders
注入到CustomerResource
类中,然后提供将访问标头的getter方法.然后在验证器类中使用@Inject
注入资源.然后,您可以从验证器访问标头.
But it is possible for the resource class to be a CDI managed bean. So you could inject the HttpHeaders
into the CustomerResource
class, and then provide a getter method that would access the headers. Then use @Inject
in your validator class to inject your resource. Then you can access the headers from the validator.
类似这样的东西:
@RequestScoped
public class PhoneNumberValidator implements ConstraintValidator<ValidPhoneNumber, String> {
@Inject
CustomerResource customerResource;
@Override
public boolean isValid(String vTelephone, ConstraintValidatorContext pContext) {
// Get the country in here using the original resource instance
final String vCountry = customerResource.getHeaderString("COUNTRY");
try {
validate(vTelephone, vCountry);
} catch (Throwable t) {
System.out.printf("Error parsing {0} as a phone number in {1}: {2}", vTelephone, vCountry, t.getMessage());
return false;
}
return true;
}
...
像这样更新资源类:
@RequestScoped
@Path("customer")
public class CustomerResource {
@Context
private HttpHeaders headers;
@POST
@Consumes(MediaType.APPLICATION_JSON)
public Response postCustomer(@Valid Customer pCustomer) {
return Response.ok(pCustomer).build();
}
String getHeaderString(String headerName) {
return headers.getHeaderString(headerName);
}
...
我在这里写了一个工作示例,可能会有所帮助: https://github.com/andymc12/ContextVarInValidatorSample
I wrote up a working sample here that may help: https://github.com/andymc12/ContextVarInValidatorSample
希望这会有所帮助,安迪
Hope this helps, Andy
这篇关于使用JAX-RS时,是否可以将变量输入到自定义ConstraintValidator中?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!