2014-04-25 57 views
7

我目前遇到了Spring中的@RequestBody註釋問題。我目前已將所有驗證註釋正確設置在我的模型上,並且在對象被POST時它們工作得很好。即使發佈的請求主體完全爲空或爲空的對象「{}」,一切都按預期工作。當有人試圖發佈「null」的請求主體時,問題就出現了。這不知何故通過@Valid批註,並且沒有捕獲,導致NullPointerException當我嘗試訪問該對象。下面我粘貼了我的控制器片段。空的請求體沒有被Spring @RequestBody @Valid註解捕獲

@Secured({ ROLE_ADMIN }) 
@RequestMapping(method = RequestMethod.POST, consumes = { MediaType.APPLICATION_JSON_VALUE }) 
public HttpEntity<Resource<Item>> addItem(@RequestBody @Valid Item item) throws Exception { 
    Resource<Item> itemResource = this.itemResourceAssembler.toResource(this.itemService.save(item)); 
    return new ResponseEntity<Resource<Item>>(itemResource, HttpStatus.CREATED); 
} 

我在做一些itemService.save()檢查是否存在於數據庫中的項目已經,因爲這是被用作更新插入。當我訪問通過保存的項目時,我得到NullPointerException,因爲項目爲空。我試過使用@RequestBody的「必需」參數,但只檢查是否有東西發佈。如上所述,只有當用戶張貼「null」而沒有引號作爲請求主體時,纔會傳遞null項。有沒有一個自動的Spring註釋或配置來阻止這個null傳遞,或者我應該把if(item == null) throw new Exception();放在所有可能出現這種情況的控制器中?

回答

2

通過您發佈的代碼片段的外觀,您有一個明確定義的服務層。我會建議使用方法級的驗證在你的服務如下

@Validated 
public interface ItemService { 

public Item save(@NotNull Item item); 

如果你使用Spring的XML配置添加到您的應用程序上下文XML。

<bean id="validator" class="org.springframework.validation.beanvalidation.LocalValidatorFactoryBean"/> 
<bean class="org.springframework.validation.beanvalidation.MethodValidationPostProcessor"/> 

一個MethodConstraintViolationException將被拋出,可能在@ControllerAdvice被抓住,如果你有一個定義。

@ExceptionHandler(MethodConstraintViolationException.class) 

快樂編碼!

+0

謝謝你rkaltreider這實際上工作完美。 – Zasrin

2

根據JSON specification,null是一個有效值。 Spring在後臺使用的Jackson將一個null JSON值反序列化爲Java null參考。

你必須做你所描述的,並在你的控制器中檢查它。或者,您可以創建自己的HandlerMethodArgumentResolver爲您做到這一點。

1

讓我們這樣說:如果一個對象不存在,那麼它不能是無效的。

@Valid不僅會導致春季檢查item對象,具有一些規則的規定。它不檢查它是否在那裏。如果請求主體爲空或空對象,則在驗證之前,進程停止。對於Spring和Jackson的默認設置,這兩種情況是不允許的。

因此,你可以檢查null或寫一個擴展名,正如@Sotirios Delimanolis指出的那樣。