是否可以有条件地分配@RequestParam 中的Required 值? [英] Is it possible to conditionally assign the value of Required in @RequestParam?

查看:37
本文介绍了是否可以有条件地分配@RequestParam 中的Required 值?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我的控制器中有 2 个 @RequestParam 参数.我想根据条件设置两个参数的必需值.条件可能是,如果传递了一个参数,则必须传递另一个.因此,将 other 的 required 设置为 true,反之亦然.否则,如果没有传递任何参数,则将两者都设置为 false.

I have 2 @RequestParam parameters in my Controller. I want to set the Required value of both the parameters based on a Condition. The condition could be like, if one of the parameter is passed, the other has to passed. So set the required of other as true and vice-versa. Otherwise set both false if none of the parameters are passed.

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

The syntax of using the variable name inside @RequestParam() is wrong, but I wanted to explain what I want.

推荐答案

您可以使用以下两种方式之一:

You can do it using one of the 2 following ways:

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

1.使用 Spring AOP

创建如下注释:

public @interface RequestParameterPairValidation {

}

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

Then you can annotate your request mapping method with it:

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

围绕注释创建一个方面.类似的东西:

Create an aspect around the annotation. Something like:

@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 是一个不错的选择.当然,这取决于上下文,但这是开始时的一般经验法则.

Note that it would be a good option to return 400 BAD REQUEST here since the request was not valid. Depends on the context, of course, but this is a general rule of thumb to start with.

2.使用 HandlerInterceptorAdapter

创建一个新的拦截器映射到您想要的 URI(在本例中为 /test):

Create a new interceptor mapping to your desired URI (in this case /test):

@Configuration  
public class CustomInterceptor extends WebMvcConfigurerAdapter  {  

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

在自定义拦截器中定义验证逻辑:

Define the logic for validation inside the custom interceptor:

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,或任何其他对您更有意义的东西.

I would say the 2nd option is the best one since you can directly control the answer of the request. In this case it might be a 400 BAD REQUEST, or anything else that makes more sense in your case.

这篇关于是否可以有条件地分配@RequestParam 中的Required 值?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆