Spring MVC能否严格映射查询字符串以请求参数?

时间:2015-07-12 05:25:23

标签: java spring spring-mvc request-mapping

有没有办法配置Spring-MVC严格接受已知的查询字符串列表?我希望验证提交的查询字符串 - 如果请求有其他查询字符串参数,我想了解它并返回404.

我的动机如下:

  • 清晰度:我不希望客户端指责请求参数,并且仍然可以获得结果(就像没有提供请求参数一样)
  • HTTP缓存:我想限制我的服务的有效HTTP路由数量,以便HTTP缓存(即清漆)更好地工作

例如,我可能有一个简单的控制器配置为一个RequestParam

@RequestMapping(value = "/selective_route", method = RequestMethod.GET)
public String printTest(@RequestParam String test) {
    return test;
}

我现在希望我的应用接受请求并返回OK响应:

/selective_route?test=foo

但我希望我的应用程序注意到还有其他未计入的请求参数,并返回ERROR响应代码。

/selective_route?test=foo&someotherparam=somethingelse

1 个答案:

答案 0 :(得分:3)

拦截器可以完成这项工作。您需要实现HandlerInterceptor并将其附加到框架。它将在每个传入请求时被调用。

执行验证的方法可以是在拦截器本身内保留有效查询字符串列表,并根据传入请求检查它们,例如使用正则表达式。

更快更干净的方法是在@RequestMapping旁边使用自定义注释。此注释将采用一个参数,同样是正则表达式或包含允许字段名称的数组。

这种注释可以声明如下:

@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
public @interface YourAnnotationName {
    public String regularExpression() default "";
}

您可以使用以下代码从拦截器中检索方法及其注释:

@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
    // Apply only to HandlerMethod
    if(!(handler instanceof HandlerMethod))
        return true;

    // Get method and annotation instance
    HandlerMethod method = (HandlerMethod) handler;
    YourAnnotationName annotation = method.getMethodAnnotation(YourAnnotationName.class);

    // Method not annotated no need to evalutate
    if(annotation == null)
        return true;

    // Validation
    String queryString = request.getQueryString();
    [...]
}