2016-12-03 144 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方法可配置。

這種'過濾器或攔截器'的方式是更好的,因爲重複使用的能力以及固體。