2016-04-21 68 views
2

我創建了一個基礎春季控制器我最新的web應用程序的項目,我從我的所有基本的CRUD控制器繼承,稱爲CrudController:繼承控制器方法不被映射與RequestMapping

class CrudController<T, K extends Serializable> 

T是實體類型,K是用於該類型的關鍵字(幾乎是Spring的CrudRepository所需的參數)。我通過擴展它,像這樣創建一個休息控制器:

@RestController 
@RequestMapping(path = "/hats") 
public class HatController extends CrudController<Hat, Integer> { 
} 

一切都很正常,除了爲獲得項目,/hats的列表的方法。用這種方法,我得到了405方法不允許。當我查看啓動過程中完成的日誌記錄時,可以看到RequestMappingHandlerMapping沒有映射{[/hats],methods=[GET]},但它確實映射了控制器中的其他四種方法。這裏是一個沒有被映射的方法的代碼:

@RequestMapping(method = RequestMethod.GET) 
public HttpEntity<?> getAll() { 
    Iterable<T> result = controllerRepository.findAll(); 
    return new ResponseEntity<Object>(result, HttpStatus.OK); 
} 

多次試驗後,我發現,如果我添加的一個參數GETALL方法是類參數類型之一,該方法將得到映射。檢查這個非常類似的代碼:

@RequestMapping(method = RequestMethod.GET) 
public HttpEntity<?> getAll(K dontuse) { 
    Iterable<T> result = controllerRepository.findAll(); 
    return new ResponseEntity<Object>(result, HttpStatus.OK); 
} 

隨着小代碼的變化,/find調用工作正常。我可以在那裏保留我的虛擬參數,一切都可以工作,但它有味道。

任何想法?可複製的問題簡化項目可以在這裏找到:

Simple Project

回答

3

中目前Java的一個bug,見bug報告herehere,其中Class#getDeclaredMethods()返回的橋樑Method每個繼承的方法從超聲明包私人。基於javadoc,它不應該這樣做。

這使Spring MVC對@Controller帶註釋的類和處理程序方法的檢查感到困惑。在這個答案中詳細說明將不會很有用,但您可以查看處理它的代碼here

最簡單的解決方案是將CrudRepository類聲明爲public

public class CrudController<T, K extends Serializable> 
+1

這是絕妙的故障排除,+1 – dimitrisli