开发者

RequestMapping on presence of one of multiple parameters

I have a Spring3 controller in which I'm using the @RequestMapping annotation. I know I can use the params value to route based on the the presence or lack of a url parameter, but is there a way to r开发者_Python百科oute based on the presence of one of two parameters?

Ideally I'd have something like the following:

@RequestMapping(value="/auth", params="error OR problem")
public ModelAndView errorInAuthenticate()

Where I route to errorInAuthenticate if the parameters error OR problem exist.


Unfortunately @RequestMapping params are combined using AND, not OR. (Source)


simply map both params as not required and test them:

@RequestMapping(value="/auth")
public ModelAndView errorInAuthenticate(@RequestParam(value="error", required=false) String errorParam, 
                                        @RequestParam(value="problem", required=false) String problemParam) {

    if(errorParam != null || problemParam != null) {
        //redirect
    }
}


You can do it using Spring AOP and create a surrounding aspect for that request mapping.

Create an annotation like the following:

public @interface RequestParameterOrValidation{
    String[] value() default {};
}

Then you can annotate your request mapping method with it:

@GetMapping("/test")
@RequestParameterOrValidation(value={"a", "b"})
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 RequestParameterOrValidationAspect {
    @Around("@annotation(x.y.z.RequestParameterOrValidation) && execution(public * *(..))")
    public Object time(final ProceedingJoinPoint joinPoint) throws Throwable {
        Object[] args= joinPoint.getArgs();

        MethodSignature methodSignature = (MethodSignature) thisJoinPoint.getStaticPart().getSignature();
        Method method = methodSignature.getMethod();
        Annotation[][] parameterAnnotations = method.getParameterAnnotations();
        RequestParameterOrValidation requestParamsOrValidation= method.getAnnotation(RequestParameterOrValidation.class);
        String[] params=requestParamsOrValidation.value();
        boolean isValid=false;
        for (int argIndex = 0; argIndex < args.length; argIndex++) {
            for (Annotation annotation : parameterAnnotations[argIndex]) {
                if (!(annotation instanceof RequestParam))
                    continue;
                RequestParam requestParam = (RequestParam) annotation;
                if (Arrays.stream(params).anyMatch(requestParam.value()::equals) && args[argIndex]!=null) {
                    // Atleast one request param exist so its a valid value
                    return joinPoint.proceed();
                }
            }
        }
       
        throw new IllegalArgumentException("illegal 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.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜