Spring boot Spring启动:请求参数中的自定义验证

Spring boot Spring启动:请求参数中的自定义验证,spring-boot,validation,controller,spring-annotations,http-request-parameters,Spring Boot,Validation,Controller,Spring Annotations,Http Request Parameters,我想验证控制器中的一个请求参数。请求参数应来自给定值列表中的一个,如果不是,则应引发错误。在下面的代码中,我希望请求参数orderBy来自@valuesallow中的值列表 @RestController @请求映射(“/api/opportunity”) @Api(value=“Opportunity Api”) @ValuesAllowed(propName=“orderBy”,values={“OpportunityCount”、“OpportunityPublishedCount”、“A

我想验证控制器中的一个请求参数。请求参数应来自给定值列表中的一个,如果不是,则应引发错误。在下面的代码中,我希望请求参数orderBy来自@valuesallow中的值列表

@RestController
@请求映射(“/api/opportunity”)
@Api(value=“Opportunity Api”)
@ValuesAllowed(propName=“orderBy”,values={“OpportunityCount”、“OpportunityPublishedCount”、“ApplicationCount”,
“ApplicationApprovedCount”})
公共类机会控制器{
@GetMapping(“/vendors/list”)
@ApiOperation(value=“获取所有供应商”)
public resultrapperdto getVendorpage(@RequestParam(required=false)字符串术语,
@RequestParam(required=false)整数页,@RequestParam(required=false)整数大小,
@RequestParam(required=false)字符串orderBy,@RequestParam(required=false)字符串sortDir){
我已经编写了一个自定义bean验证器,但不知怎么的,它不起作用。即使我为查询参数传递任何随机值,它也不会进行验证并抛出错误

@Repeatable(ValuesAllowedMultiple.class)
@目标({ElementType.TYPE})
@保留(RetentionPolicy.RUNTIME)
@约束(validatedBy={ValuesAllowedValidator.class})
public@interface ValuesAllowed{
字符串消息()默认值“字段值应来自列表”;
类[]组()默认值{};

类情况1:如果注释值sallow根本没有触发,可能是因为没有用@Validated注释控制器

@已验证
@ValuesAllowed(propName=“orderBy”,values={“OpportunityCount”、“OpportunityPublishedCount”、“ApplicationCount”、“ApplicationApprovedCount”})
公共类机会控制器{
@GetMapping(“/vendors/list”)
公共字符串getVendorpage(@RequestParam(required=false)字符串术语{
}
案例2:如果它被触发并引发错误,可能是因为
BeanUtils.getProperty
没有解析属性并引发异常

如果上述解决方案不起作用,您可以尝试将注释移动到方法级别,并更新验证器以使用
OrderBy
参数的有效值列表。这对我来说很有效。下面是示例代码

@RestController
@请求映射(“/api/opportunity”)
@验证
公共类机会控制器{
@GetMapping(“/vendors/list”)
公共字符串getVendorpage(@RequestParam(required=false)字符串术语,
@RequestParam(required=false)整数页,@RequestParam(required=false)整数大小,
@ValuesAllowed(propName=“orderBy”,values={“OpportunityCount”、“OpportunityPublishedCount”、“ApplicationCount”,
“ApplicationApprovedCount”})@RequestParam(required=false)字符串orderBy、@RequestParam(required=false)字符串sortDir){
返回“成功”;
}
@Retention(RetentionPolicy.RUNTIME)
@约束(validatedBy={ValuesAllowed.Validator.class})
public@interface ValuesAllowed{
字符串消息()默认值“字段值应来自列表”;
类[]组()默认值{};
班级
要使验证生效,您只需更改几件事

控制器应使用
@Validated
进行注释,
@valuesallow
应在方法中注释目标参数

import org.springframework.validation.annotation.Validated;
导入org.springframework.web.bind.annotation.GetMapping;
导入org.springframework.web.bind.annotation.RequestMapping;
导入org.springframework.web.bind.annotation.RequestParam;
导入org.springframework.web.bind.annotation.RestController;
@验证
@RestController
@请求映射(“/api/opportunity”)
公共类机会控制器{
@GetMapping(“/vendors/list”)
公共字符串getVendorpage(
@RequestParam(必需=false)
@值已删除(值={
“机会主义计数”,
“OpportunityPublishedCount”,
“应用程序帐户”,
“应用程序批准计数”
})字符串orderBy,
@RequestParam(必需=false)字符串术语,
@RequestParam(required=false)整数页,@RequestParam(required=false)整数大小,
@RequestParam(必需=false)字符串(sortDir){
返回“OK”;
}
}
@ValuesAllowed
应该以
ElementType.PARAMETER
为目标,在这种情况下,您不再需要
propName
属性,因为Spring将验证所需的参数

import javax.validation.Constraint;
导入javax.validation.Payload;
导入java.lang.annotation.ElementType;
导入java.lang.annotation.Retention;
导入java.lang.annotation.RetentionPolicy;
导入java.lang.annotation.Target;
@目标({ElementType.PARAMETER})
@保留(RetentionPolicy.RUNTIME)
@约束(validatedBy={ValuesAllowedValidator.class})
public@interface ValuesAllowed{
字符串消息()默认值“字段值应来自列表”;
类[]组()默认值{};

ClassYour代码运行良好。但是我如何使此值可重用Sallowed validator,现在允许值的数组在类中是硬编码的,请编辑您的答案以使代码可重用以验证任何字段。我已编辑了答案以通过控制器传递值。通常,您可以从如果您使用的是请求Bean,则控制器或注释字段。添加valuesallowed注释后,请求参数成为必需参数,如何将其设置为可选参数。好的,
@RequestParam
验证程序在这里分别工作。要将其设置为可选参数,我们可以在验证程序中返回true为值传入null。Code-Boolean valid=value==null | | this.allowed.co