2010-04-30 84 views
37

有沒有一種方法可以表達我的Spring Web MVC控制器方法應該通過作爲URI路徑的一部分傳遞一個ID的請求來匹配......Spring Web MVC:對請求參數和路徑變量使用相同的請求映射

@RequestMapping(method=RequestMethod.GET, value="campaigns/{id}") 
public String getCampaignDetails(Model model, @PathVariable("id") Long id) { 

...或者,如果客戶端的ID作爲風格HTTP請求參數發送...

@RequestMapping(method=RequestMethod.GET, value="campaigns") 
public String getCampaignDetails(Model model, @RequestParam("id") Long id) { 

這在我看來很常見的真實世界的URL方案,我不想添加重複的代碼,但我還沒有找到答案。任何建議非常歡迎。

編輯:事實證明,似乎目前(與Spring MVC的< = 3.0)沒有辦法做到這一點,看到哈維的回答中討論。

回答

50

您可以爲同一個函數設置兩個映射url,並設置id爲可選項。

@RequestMapping(method=RequestMethod.GET, value={"/campaigns","/campaigns/{id}"}) 
public String getCampaignDetails(Model model, 
    @RequestParam(value="id", required=false) Long id, 
    @PathVariable("id") Long id2) 
{ 
} 

雖然它會映射以及id沒有發送,但你可以控制這個方法裏面。

編輯:以前的解決方案不起作用,因爲@PathVariable未設置爲null當沒有{null},它不能映射URL(感謝ngeek)。我認爲唯一可行的解​​決方案是創建兩個方法,每個方法都使用@MappingRequest映射,其中一個調用另一個函數或重定向到另一個URL(重定向:或forward:Spring前綴)。我知道這個解決方案不是你想要的,但認爲這是你能做的最好的。事實上,你沒有複製代碼,但你正在創建另一個函數來處理另一個URL。

+1

不幸的是,這是行不通的,因爲路徑變量無法解析。我還嘗試了一種方法,通過添加方法參數(@PathVariable(「id」)Long id2),但是不能將路徑變量設置爲可選項,因此此建議的解決方案不起作用。 更多推薦? – ngeek 2010-05-01 09:55:56

+0

@ngeek我沒有意識到@PathVariable不能設置爲null,謝謝。我也忘了寫@PathVariable,所以我編輯了我的答案來添加它,我認爲你不能避免有2種方法,我認爲:(。 – Javi 2010-05-01 14:09:51

+1

謝謝你回到你的提議Javi。當然我已經委託給我仍然認爲Spring MVC註釋應該提供一種方法來根據內在的意思將多個URL定義映射到相同的方法,就像Rails或Grails中已經允許的路由器一樣。 感謝您的幫助無論如何, – ngeek 2010-05-02 14:37:26

4

如果你仍然要堅持PathVariable的方法,如果你得到400語法不正確的錯誤然後按照這個approach-

@RequestMapping(method=RequestMethod.GET, value={"campaigns/{id}","campaigns"}) 
         public String getCampaignDetails(Model model, 
         @PathVariable Map<String, String> pathVariables) 
    { 

    System.out.println(pathVariables.get("id")); 

    } 
1

@RequestMapping註釋現在支持設置path屬性而不是namevalue。使用path,您可以實現此問題所需的映射:

@RequestMapping(method=RequestMethod.GET, path="campaigns/{id}") 
public String getCampaignDetails(Model model, @PathVariable("id") Long id) { 

@RequestMapping(method=RequestMethod.GET, value="campaigns") 
public String getCampaignDetails(Model model, @RequestParam("id") Long id) {