使用Spring框架检测无效的URL参数

时间:2016-12-03 18:06:49

标签: java spring url parameters

在Spring框架中有一种很好的方法来检测传入的URL何时具有无效参数?似乎默认行为是忽略无法识别的参数。我能找到的最佳解决方案是将参数映射添加到我的所有端点,并根据预期的参数检查映射。

例如,假设我有一个带有集合端点的小部件站点。

@RequestMapping(value = "/widgets", method = RequestMethod.GET)
public ResponseEntity<WidgetList> getWidgets(
        @RequestParam(value = "search", required = false) String search) {
    // ...
    // Get list of widgets
    // ...
    return new ResponseEntity<WidgetList>(widgetList, HttpStatus.OK);
}

“search”参数是可选的,因为将其删除是一种便利,可以找到所有小部件。我支持搜索语法,以便下面找到foo属性值为bar

的小部件
GET https://example.com/widgets?search=foo:bar

用户输错字

GET https://example.com/widgets?saerch=foo:bar

这无声地失败了。所有人都找到了,而不是找到foo = bar的小部件。我希望它返回400错误,指出不支持“saerch”参数。一个很好的答案是RequestMapping上的某种严格选项,如下所示。

@RequestMapping(value = "/widgets", method = RequestMethod.GET, paramsStrict = true)
public ResponseEntity<WidgetList> getWidgets(
        @RequestParam(value = "search", required = false) String search) {
    // ...
    // Get list of widgets
    // ...
    return new ResponseEntity<WidgetList>(widgetList, HttpStatus.OK);
}

据我所知,这种情况不存在。我还没有想出一个干净的方法来拦截请求并检查所有方法(并以某种方式告知哪些参数对每个方法都有效)。到目前为止,我发现的最好的方法是添加一个参数图,并在每个控制器方法中检查地图与接受的参数。

@RequestMapping(value = "/widgets", method = RequestMethod.GET, produces = MediaType.APPLICATION_JSON_VALUE)
public ResponseEntity<WidgetList> getWidgets(
        @RequestParam(value = "search", required = false) String search, 
        @RequestParam Map<String, String> allRequestParams) {
    validateParameters(allRequestParms);
    // ...
    // Get list of widgets
    // ...
    return new ResponseEntity<WidgetList>(widgetList, HttpStatus.OK);
}

有更好的方法吗?

请不要发布有关我的设计的答案或如何使搜索参数成为必需。这只是我想用一个简单的例子来做的。在我的实际应用程序中,存在设计良好的情况,其中检查无效参数名称将是有用的。

1 个答案:

答案 0 :(得分:0)

您可以实施自己的Servlet FilterHandlerInterceptor来验证参数。

以下示例使用过滤器:

public class ParametersValidationFilter implements Filter {
    @Override
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
        if (validateParameters((HttpServletRequest)request, (HttpServletResponse)response)) {
            chain.doFilter(request, response);
        }
    }

    private boolean validateParameters(HttpServletRequest request, HttpServletResponse response) {
        // Check parameter names in request.getParameterNames()
        /*
        Invalid parameter yields response.setStatus(HttpServletReponse.SC_BAD_REQUEST)
        and additional info in response body
        */

        // Otherwise, validation succeeds:
        return true;
    }

    /* Other methods */
}

此外,Filter可以使用init方法进行配置。

这种“过滤器或拦截器”方式更好,因为它可以重复使用SOLID。