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,) {
{
}
}
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. Using Spring AOP
Create an annotation like the following:
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");
}
}
}
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. Using HandlerInterceptorAdapter
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
}
}
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With