2016-12-03 142 views
0

在Spring框架内检测传入URL有无效参数的时候有没有一种好方法?看起来默认行为是忽略无法识别的参数。我可以找到的最佳解决方案包括向所有端点添加参数映射,并根据它所期望的参数检查映射。使用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); 
} 

“搜索”参数是可选的,因为将它留出是一种方便,可以找到所有小部件。我支持一个搜索语法使得下列发现窗口小部件,其中FOO属性具有巴的值

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); 
} 

有没有更好的方法来做到这一点?

请不要发布关于我的设计或我如何能够使搜索参数所需的答案。这只是我试图用一个简单的例子来说明的一点。在我的真实世界的应用程序中,有精心设计的案例,检查无效的参数名称会很有用。

回答

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 */ 
} 

此外,过滤器可以与init方法可配置。

这种'过滤器或拦截器'的方式是更好的,因为重复使用的能力以及固体。