所以我的控制器中有一个GET方法,带有可选的请求参数:
@GetMapping(path = "/users/search")
public @ResponseBody ResponseEntity<List<User>> getUserLike(
@RequestParam(name = "id", required = false) Long id,
@RequestParam(name = "name", required = false) String name,
@RequestParam(name = "dateofbirth", required = false) @DateTimeFormat(pattern = "dd-MM-yyyy") LocalDate dateOfBirth
) {
return userService.getUserLike(id, name, dateOfBirth);
}
当我试图用未知参数调用此请求时,
/users/search?id=1&myunknownparam=unknownParam
当请求具有未知参数时,我想引发一个异常,例如myunknownparam。
尽管目前我的所有参数都是可选的,但我的服务返回的结果与所有参数设置为null时的结果相同。
@GetMapping(path = "/users/search")
public @ResponseBody
ResponseEntity<List<User>> getUserLike(
@RequestParam Map<String, String> allParams,
@RequestParam(name = "id", required = false) Long id,
@RequestParam(name = "name", required = false) String name,
@RequestParam(name = "dateofbirth", required = false) @DateTimeFormat(pattern = "dd-MM-yyyy") LocalDate dateOfBirth
) {
// here check if allParams contains only valid keys
return userService.getUserLike(id, name, dateOfBirth);
}
查询参数通常是可选的,因此服务器很少会因此拒绝您
但是您试图实现的目标可以用Interceptor实现,您需要一些反射来获得方法的参数,并验证每个客户端参数是否在方法的签名上定义。
类似于:
@Component
public class QueryParamInterceptor implements HandlerInterceptor {
@Override
public boolean preHandle(final HttpServletRequest request, final HttpServletResponse response, final Object handler) {
Map<String, String[]> clientRequestParameters = request.getParameterMap();
MethodParameter[] methodParameters = ((HandlerMethod) handler).getMethodParameters();
List<String> definedMethodsParameters = Arrays.stream(methodParameters)
.flatMap(methodParameter -> Arrays.stream(methodParameter.getParameterAnnotations()))
.filter(annotation -> annotation.annotationType().isAssignableFrom(RequestParam.class))
.map(annotation -> ((RequestParam) annotation).name())
.collect(Collectors.toList());
for (String clientRequestParameterKey : clientRequestParameters.keySet()) {
if (!definedMethodsParameters.contains(clientRequestParameterKey)) {
throw new IllegalArgumentException("The parameter " + clientRequestParameterKey + " passed by the client is unknown");
}
}
return true;
}
}
请注意,每次请求都会调用一个拦截器。所以我不会在生产中使用它,因为对象内省的成本很高。。