是否可以有条件地分配所需的@RequestParam价值?

问题描述 投票:2回答:4

我有我的控制器2个@RequestParam参数。我想设置都基于一个条件参数的要求值。该条件也能像,如果参数之一传递外,其他已过去了。因此,设置所需的其他如真,反之亦然。如果没有参数传递,否则设置这两个假。

@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()变量名的语法是错误的,但我想解释我想要什么。

java spring rest spring-boot
4个回答
1
投票

您可以使用的2种下列方式之一它:

  1. 使用Spring AOP并创建该请求映射周围方面
  2. 使用HandlerInterceptorAdapter拦截对于一个给定的URI请求

1.使用Spring AOP

创建类似下面的注释:

public @interface RequestParameterPairValidation {

}

然后,你可以用它来注解你的请求映射方法:

@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

创建一个新的拦截器映射到你想要的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,或其他任何东西,更有意义,你的情况。


0
投票

您可以以智能的方式在这里使用可选的位置是这样的:

@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
}

我希望这个作品对您的要求。


0
投票

您可以使用Java EE @Size的验证注解与Spring(但你必须有classpath中的Java EE的验证API实现者,即休眠)。与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) {
     {

     }

}

-1
投票

在Java中,你可以通过唯一不变的任何注释的参数。这就是为什么它是不可能做这种方式。但是,您可以验证所有的那种方法本身的东西。

© www.soinside.com 2019 - 2024. All rights reserved.