2013-08-22 47 views
1

我們正在研究基於REST的服務,並且我們正在使用Spring MVC。我們正面臨一個解決方法問題的網址。這大概就是我們正在嘗試做的區分URL和路徑參數

假設我們有自己的寵物

//Class level request mapping 
@RequestMapping("/persons") 

// Mapping to access a specific person inside one of the methods 
@RequestMapping(value="/{personId}", method= RequestMethod.GET 
//.... getPerson method 


// Mapping to access a specific person's pets inside one of the methods 
@RequestMapping(value="/{personId}/pets", method= RequestMethod.GET 
// getPersonPets method 

人如果請求當屬「/人/ P12323233」,其中P12323233是人的ID,它解析爲getPerson方法。 如果請求以「/ persons/P12323233/pets」的形式出現,其中P12323233是person id,則它將解析爲getPersonPets方法。

所以一切都很好,直到現在。但是 如果請求以「/ persons/pets」的形式出現,請求會解析爲getPerson方法。雖然我們可以在getPerson方法中將其作爲一個錯誤情況處理,但我們試圖檢查是否有解決此問題的方法getPersonPets方法。

我們仍在爭論來處理這種情況的正確的地方是否是getPerson或getPersonPets方法。這樣的爭論不談,我們想知道它是否能達到該getPersonPets方法解決,甚至在技術上具有可行性。

感謝任何幫助

+0

的URL映射清楚的第一種方法。所以如果''「寵物」是一個人的現有ID,它應該返回這個人。如果不是,它應該返回一個404 Not Found錯誤。調用'getPersonPets()'沒有什麼意義,並且無論如何你都不能返回任何有用的東西,因爲你沒有任何人的ID來找到寵物。我會立即結束辯論:) –

+0

它是有道理的,當有一個網址/個人/寵物它會嘗試調用第一個方法,並會嘗試找到身份證「寵物」的人。如果它沒有找到,它會給出404。在這種情況下,第二種方法將永遠不會執行。 thnx的寶貴意見。 – user2707141

回答

1

這可以通過爲同一方法添加多個映射來解決:

@RequestMapping(value="/{personId}", method= RequestMethod.GET 
//.... getPerson method 

@RequestMapping(value = {"/{personId}/pets", "/pets"}, method= RequestMethod.GET 
// getPersonPets method 

更新: 注意,訪問/寵物時使用以下簽名會拋出異常的PERSONID是不存在的網址:

public String showPets(@PathVariable("personId") long personId) 

這將是這是訪問變量的最方便的方法,但由於我們有多個路徑映射相同的方法,我們可以將簽名更改爲以下內容以避免發生異常:

public String showPets(@PathVariable Map<String, String> vars) 

和檢索從地圖路徑變量

+0

使用multipe映射它解決了進入錯誤方法的問題。但是當我嘗試調用/個人/寵物時,它給了我一個彈簧異常,說明未提供路徑變量。 – user2707141

+0

對,如果您在註釋中明確定義了路徑變量名稱,那麼當它在URL中不存在時會得到一個異常。您可以將您的簽名方法更改爲: public String showPets(@PathVariable Map vars){...} 並從地圖獲取路徑變量 –

1

你也可以使用正則表達式,並篩選出這種請求404例如:

// Mapping to access a specific person inside one of the methods 
@RequestMapping(value="/{personId:P[\\d]+}", method= RequestMethod.GET 
//.... getPerson method 


// Mapping to access a specific person's pets inside one of the methods 
@RequestMapping(value="/{personId:P[\\d]+}/pets", method= RequestMethod.GET 
// getPersonPets method 
+0

注意:fixed regex \\ d - > \\ d – ikumen

+0

我嘗試過使用正則表達式來做這件事。當/ persons/pets被調用時..它沒有調用第一個方法,但它給出了一個錯誤,說明沒有找到http 404請求的資源。 – user2707141

+0

如果你說可以擁有/人/寵物,那麼你是正確的,這些映射將無法正常工作。所以/人/寵物/寵物是可能的?正則表達式的基礎是你的問題,並假設一個人身份證的形式是P ###### ..,在這種情況下,那麼/個人/寵物是無效映射,並會返回404。 – ikumen

0

雖然一般REST假設你引用一個ID當您沒有在資源上指定段時,我喜歡添加id,以使其他端點不明確。

考慮做以下的,如果你被允許更改API:

//Class level request mapping 
@RequestMapping("/persons") 

// Mapping to access a specific person inside one of the methods 
@RequestMapping(value="/id/{personId}", method= RequestMethod.GET 
//.... getPerson method 


// Mapping to access a specific person's pets inside one of the methods 
@RequestMapping(value="/id/{personId}/pets", method= RequestMethod.GET 
// getPersonPets method