java—是否可以在@requestparam中有条件地分配required的值?

slhcrj9b  于 2021-07-09  发布在  Java
关注(0)|答案(4)|浏览(341)

我的控制器中有2个@requestparam参数。我想根据一个条件设置两个参数的所需值。条件可能类似于,如果一个参数被传递,另一个必须被传递。因此,将“其他”的要求设置为true,反之亦然。否则,如果没有传递任何参数,则将这两个都设置为false。

@RestController
public class TestController {

@GetMapping("/test")
public void test(@RequestParam(value = "a", required = (b !=null) String a, 
@RequestParam(value = "b", required = (a !=null) )  String b,) {
     {

     }

}

在@requestparam()中使用变量名的语法是错误的,但我想解释一下我想要什么。

ndasle7k

ndasle7k1#

您可以使用以下两种方法之一:
使用springaop并为该请求Map创建一个环境方面
使用handlerinterceptoradapter拦截给定uri的请求
1.使用spring aop
创建注解,如下所示:

public @interface RequestParameterPairValidation {

}

然后可以用它来注解请求Map方法:

@GetMapping("/test")
@RequestParameterPairValidation
public void test(
   @RequestParam(value = "a", required = false) String a, 
   @RequestParam(value = "b", required = false)  String b) {
      // API code goes here...
}

围绕注解创建一个方面。比如:

@Aspect
@Component
public class RequestParameterPairValidationAspect {
    @Around("@annotation(x.y.z.RequestParameterPairValidation) && execution(public * *(..))")
    public Object time(final ProceedingJoinPoint joinPoint) throws Throwable {
        Object[] requestMappingArgs = joinPoint.getArgs();
        String a = (String) requestMappingArgs[0];
        String b = (String) requestMappingArgs[1];

        boolean requestIsValid = //... execute validation logic here

        if (requestIsValid) {
           return joinPoint.proceed();
        } else {
           throw new IllegalArgumentException("illegal request");
        }
    }
}

请注意,这将是一个很好的选择返回 400 BAD REQUEST 因为请求无效。当然,这取决于上下文,但这是一个一般的经验法则。
2.使用handlerinterceptoradapter
创建一个新的拦截器Map到所需的uri(在本例中为 /test ):

@Configuration  
public class CustomInterceptor extends WebMvcConfigurerAdapter  {  

    @Override
    public void addInterceptors(InterceptorRegistry registry) {
       registry
         .addInterceptor(new CustomRequestParameterPairInterceptor())
         .addPathPatterns("/test");
    }
}

定义自定义拦截器内部的验证逻辑:

public class CustomRequestParameterPairInterceptor extends HandlerInterceptorAdapter {

    @Override
    public void afterCompletion(HttpServletRequest req, HttpServletResponse res, Object obj, Exception exception) throws Exception {

    }

    @Override
    public void postHandle(HttpServletRequest req, HttpServletResponse res, Object obj, ModelAndView modelAndView) throws Exception {

    }

    @Override
    public boolean preHandle(HttpServletRequest req, HttpServletResponse res, Object handler) throws Exception {
       // Run your validation logic here
    }
}

我认为第二个选项是最好的,因为你可以直接控制请求的答案。在这种情况下,它可能是一个 400 BAD REQUEST ,或者任何对你来说更有意义的事情。

dsf9zpds

dsf9zpds2#

在java中,只能将常量作为任何注解的参数传递。这就是为什么这样做是不可能的。但是,您可以在方法本身中验证所有这些内容。

0lvr5msh

0lvr5msh3#

您可以在此处以如下智能方式使用可选选项:

@GetMapping("/test")
@RequestParameterPairValidation
public void test(@RequestParam("a") Optional<String> a,
    @RequestParam("b") Optional<String> b){

    String aVal = a.isPresent() ? a.get() : null;
    String bVal = b.isPresent() ? b.get() : null;

    //go for service call here based on your logic
}

我希望这能满足你的要求。

x8goxv8g

x8goxv8g4#

您可以在spring中使用javaee@size验证注解(但必须在类路径上有javaee验证api实现程序,即hibernate)。使用hibernate,可以使用maven导入此依赖项

<dependency>
    <groupId>org.hibernate</groupId>
    <artifactId>hibernate-validator</artifactId>
    <version>6.0.10.Final</version>
</dependency>

然后整个事情就变成了:

@RestController
@Validated
public class TestController {

@GetMapping("/test")
public void test(@RequestParam(value = "a", required = true )  @Size(min=1) String a, 
@RequestParam(value = "b", required = true) @Size(min=1)   String b) {
     {

     }

}

相关问题