2017-02-09 63 views
0

我想在春天做一個PUT調用。既不@RequestBody也不@RequestParam工作

這是我的控制器代碼:

@RequestMapping(value = "/magic", method = RequestMethod.PUT) 
    TodoDTO magic(@RequestBody String id){ 
     return service.magic(id); 
    } 

,因爲我想通過在呼叫ID字符串。

的問題是,我收到此

{ 
    "timestamp": 1486644310464, 
    "status": 500, 
    "error": "Internal Server Error", 
    "exception": "java.lang.NullPointerException", 
    "message": "{\n\t\"id\":\"589c5e322abb5f28631ef2cc\"\n}", 
    "path": "/api/todo/magic" 
} 

如果我改變這樣的代碼:

@RequestMapping(value = "/magic", method = RequestMethod.PUT) 
    TodoDTO magic(@RequestParam(value = "id") String id){ 
     return service.magic(id); 
    } 

我收到

{ 
    "timestamp": 1486644539977, 
    "status": 400, 
    "error": "Bad Request", 
    "exception": "org.springframework.web.bind.MissingServletRequestParameterException", 
    "message": "Required String parameter 'id' is not present", 
    "path": "/api/todo/magic" 
} 

我做出同樣的呼叫,PUT在鏈接http://localhost:8080/api/todo/magic 與身體

{ 
    "id":"589c5e322abb5f28631ef2cc" 
} 

這是我的數據庫中的一個對象的ID。

我的問題是,我該如何實現我的目標?如果我的鏈接,如API/TODO /魔法/ 589c5e322abb5f28631ef2cc,與@PathVariable通過帕拉姆,它的工作原理

+0

_「with @PathVariable,It works」_然後使用它。如果你不發送數據,不要使用'PUT'。 – zeroflagL

+0

@zeroflagL在URL中發送數據不是一種反模式嗎?這只是一個測試,這就是不做任何事情的原因:) – AvramPop

+0

如果你的方法的要點是返回一個項目或基於某個id,那麼這個id不是真正的數據。如果ID實際上是數據,那麼你是對的,它應該作爲正文發送。但基於錯誤消息,你沒有這樣做。 – zeroflagL

回答

5

創建自己的自定義類像下面

Class Request 
{ 
private String id; 
//getter and setter 
} 

及更換方法來

@RequestMapping(value = "/magic", method = RequestMethod.PUT) 
    TodoDTO magic(@RequestBody Request request){ 
     return service.magic(request.getId()); 
    } 

您可以在ID也URL和方法簽名使用@Pathvariable

@RequestMapping(value = "/magic/{id}", method = RequestMethod.PUT) 
     TodoDTO magic(@PathVariable String id){ 
      return service.magic(request.getId()); 
     } 
+0

是否有任何情況下,這應該是首選,而不是一個簡單的地圖? – AvramPop

+3

**未使用地圖的原因:1)建議的解決方案爲您提供了對預期輸入的類型安全訪問,地圖強制您使用使用鍵獲取數據並檢查類型是否您期望的,然後纔可用。 2)對於閱讀代碼的其他開發人員也很清楚。 3)它允許自動生成API-doc(使用spring fox)。 4)如果配置正確,傑克遜映射器可以警告用戶,如果他們使用不正確的請求值,而地圖接受身體的任何屬性。 5)如果你有嵌套的JSON結構,你將最終得到地圖中的地圖(甚至是轉換錯誤)。 –

+0

然後這是正確的答案!謝謝! – AvramPop

2

當你使用@RequestBody String id預計只是一個字符串:

"589c5e322abb5f28631ef2cc" 

如果你想與id現場發送對象像

{ 
    "id":"589c5e322abb5f28631ef2cc" 
} 

你應該創建一個類id場和修改方法的簽名得到這個類而不是String

+0

如果我有2個參數,只需用逗號分隔它們? – AvramPop

+1

不,由於'@ RequestBody'代表整個請求體,在2個參數的情況下,你必須爲它們(或你的Map)創建一個類。 –

+0

所以這個選項只適用於1個參數。感謝你的這個捷徑! – AvramPop

0

在其他答案中建議的創建包裝類時,我認爲可以避免這種開銷並簡單地使用Map。

@RequestMapping(value = "/magic", method = RequestMethod.PUT) 
    TodoDTO magic(@RequestBody Map<String, String> data){ 
     return service.magic(data.get("id"); 
} 
+0

這似乎是最好的選擇,因爲它不需要額外的類。如果我想要2個參數,只需調用data.get(「foo」)? – AvramPop

相關問題