2013-05-14 228 views
2

我有一個Spring 3.2應用程序,我創建了一個使用基於令牌的安全性的REST API。每個REST JSON有效內容都包含一個用於執行安全驗證的「令牌」字段。Spring 3 MVC請求驗證

控制器的方法是這樣的:

@RequestMapping(value = "/something", method = RequestMethod.POST) 
public 
@ResponseBody 
Map something(@RequestBody SomethingParams params) { 
} 

其中SomethingParams具有token場,並通過彈簧從請求的JSON體自動填充。

有沒有辦法在所有控制器方法上自動調用驗證器來檢查像SomethingParams這樣的參數是否有一個有效的標記?

此前我使用過一個Interceptor,並且該標記包含在查詢字符串中,但現在,由於它位於請求的主體中,我必須在攔截器中解析JSON以檢查它。既然Spring已經解析了JSON來綁定這些參數,我很好奇是否有更聰明的方法。理想情況下只需要一些全局或控制器級別的設置(而不是每種方法)。

+0

http://static.springsource.org/spring/docs/3.0.0.RC3/reference/html/ch05s07.html – Bart 2013-05-14 13:25:34

回答

3

對於這種情況,您可以使用彈簧Validator

@Component 
public class SomethingParamsValidator implements Validator { 
    @Override 
    public boolean supports(Class<?> clazz) { 
    return clazz.isAssignableFrom(SomethingParams.class); 
    } 

    @Override 
    public void validate(Object o, Errors errors) { 
    SomethingParams sp = (SomethingParams)o; 
    validateToken(sp.getToken(), errors); 
    } 

    private void validateToken(String token, Errors errors) { 
    if (!TokenUtils.isValid(token)) { 
     errors.rejectValue("token", "foo", "Token is invalid"); 
    } 
    } 
} 

然後你在Controller註冊它通過添加下面的方法

@Autowired 
SomethingParamsValidator somethingParamsValidator; 

@InitBinder 
protected void initBinder(WebDataBinder binder) { 
    binder.setValidator(somethingParamsValidator); 
} 

最後,所有你需要補充的是@Valid註釋您SomethingParams對象上,它會被驗證。

@RequestMapping(value = "/something", method = RequestMethod.POST) 
public @ResponseBody Map something(@Valid @RequestBody SomethingParams params) { 
    // ... 
} 
+0

有沒有辦法避免使用上的每一個方法的註釋@Valid?比如在參數類中指定它? – Mari9 2013-05-14 13:38:00

+0

不是我所知道的 – Alex 2013-05-14 15:11:39

0

您可以製作帶有標記字段的基類,標註爲JSR-303 @NotNull並從中擴展。

public class ParamsBase { 
    @NotNull 
    private String token; 
    // getters, setters ... 
} 
public class SomethingParams extends ParamsBase {...} 

然後就是紀念參數與@Valid

@RequestMapping(value = "/something", method = RequestMethod.POST) 
public @ResponseBody Map something(@Valid @RequestBody SomethingParams params) { 
    // ... 
} 

Spring會自動驗證參數與在運行時使用JSR-303實現。

我通常使用hibernate-validator爲實現供應商:

<dependency> 
    <groupId>org.hibernate</groupId> 
    <artifactId>hibernate-validator</artifactId> 
    <version>5.0.1.Final</version> 
</dependency> 
0

您也可以實現自己的Aspect,這將攔截所有控制器的方法和驗證PARAMS。這會給你機會擺脫@Valid註釋。 但不幸的是我沒有時間做完整的例子。