【问题标题】:Rejecting GET requests with additional query params使用额外的查询参数拒绝 GET 请求
【发布时间】:2022-02-01 07:35:24
【问题描述】:

我有一个接受一些查询参数的 HTTP GET 端点:

@GetMapping("/cat")
public ResponseEntity<Cat> getCat(@RequestParam("catName") String catName){ ...

如果客户端将发送额外的查询参数,端点将忽略它们。

GET .../cat?catName=Oscar                Getting Oscar
GET .../cat?catName=Oscar&gender=male    Getting Oscar
GET .../cat?catName=Oscar&x=y            Getting Oscar

我想拒绝发送额外查询参数的 HTTP 请求:

GET .../cat?catName=Oscar                OK
GET .../cat?catName=Oscar&gender=male    Reject (HTTP error code XYZ)
GET .../cat?catName=Oscar&x=y            Reject (HTTP error code XYZ)

我可以更改方法的签名以接受地图并按照建议 here 验证地图中的值。

有没有办法在保持更简洁和自我解释的方法签名的同时?

【问题讨论】:

  • 如果你在你的控制器方法中加入注解@RequestParam 和正确的字段,每个有更多或不同参数的请求都会被拒绝。我认为您无需执行任何操作,除非您想要自定义异常,您可以创建一个并针对这种情况发送特定的代码错误。
  • 您还可以使用不可接受的参数创建其他方法,并在这些方法中返回您的自定义错误代码。

标签: java spring-boot http spring-mvc


【解决方案1】:

您可以尝试实现HandlerInterceptor 并在preHandle() 中验证此类规则。如果请求包含控制器方法中未定义的查询参数,则只需抛出特定类型的Exception 并配置@ControllerAdvice 来处理此异常。类似的东西:

public class FooHandlerInterceptor implements HandlerInterceptor {

    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)
            throws Exception {

        if (handler instanceof HandlerMethod) {
            HandlerMethod hm = (HandlerMethod) handler;

            Set<String> allowQueryParams = Stream.of(hm.getMethodParameters())
                    .map(p -> p.getParameterAnnotation(RequestParam.class))
                    .map(req -> req.value())
                    .collect(toSet());

            for (String currentRequestParamName : request.getParameterMap().keySet()) {
                if (!allowQueryParams.contains(currentRequestParamName)) {
                    throw new FooRestException();
                }
            }
        }

        return true;
    }
}

还有@ControllerAdvice 来处理异常:

@ControllerAdvice
public class FooExceptionHandler {

    @ExceptionHandler(FooRestException.class)
    public ResponseEntity<Object> handle(FooRestException ex) {
        return new ResponseEntity<>("Some query parameter are not defined", HttpStatus.BAD_REQUEST);
    }
}

最后注册FooHandlerInterceptor使用它:

@Configuration
public class WebConfig implements WebMvcConfigurer {
    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        registry.addInterceptor(new FooHandlerInterceptor());
    }
} 

我只是向你展示这个想法。如果您希望此类检查仅应用于特定的控制器方法,您可以进一步调整 HandlerInterceptor 中的代码。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2019-04-16
    • 1970-01-01
    • 2015-12-25
    • 1970-01-01
    • 1970-01-01
    • 2021-08-28
    • 2010-12-02
    • 1970-01-01
    相关资源
    最近更新 更多