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.
精彩评论