[英]Spring REST @RequestBody is always empty
因此,在我修復了“415 media not supported”錯誤( 不支持 415 media )之后,我遇到了一個新問題。 我的RequestBody
總是空的。 當我通過Chrome PostMan發送請求時,我總是得到一個只有空值的序列化實體。 我在我的項目中使用Spring (4.2.3.RELEASE)
、 Jackson-databind (2.6.3)
和jackson-core (2.6.3)
。 我在我的項目中使用基於注釋的配置( @EnableWebMvc
使 spring 自動發現HTTPMessageConverters
)。
其他職位
我知道關於 stackoverflow 的其他帖子,幾乎有同樣的問題。 然而他們沒有給我答案。 此外,大多數帖子都是針對較舊的 Spring 版本(4.0 之前),所以現在有些事情已經大不相同了。
類似帖子:
Spring 的 @RequestBody 在 POST 上提供空字符串
彈簧控制器
在我的 Spring @RestController
我有以下代碼:
@RequestMapping(value = "/location/update/{id}", method = RequestMethod.PUT)
public UserLocation updateUserLocation(@PathVariable("id") int id, UserLocation user) {
return user;
}
我正在為我的數據綁定使用單獨的模型類 ( UserLocation
)。 這是因為這樣我可以更好地控制 API 發送和接收的數據。
數據綁定類(UserLocation)
UserLocation 類包含 3 個帶有構造函數和所需的 getter 和 setter 的屬性。 (我可以公開這些屬性,但我首先想解決這個問題)。
public class UserLocation {
private Float latitude;
private Float longitude;
private Date lastActive;
}
JSON 正文
通過我的 AngularJS Ajax 調用( $http.PUT
),我使用以下數據調用 spring 控制器:
{
"latitude": 52.899370,
"longitude": 5.804548,
"lastActive": 1449052628407
}
郵遞員請求
我正在開發一個 Cordova 應用程序,所以為了測試請求而不需要將我的應用程序構建到我的手機上,我正在使用Chrome PostMan 插件。
我正在撥打以下電話:
URL:
http://server:port/app/location/update/1
Method:
PUT
Headers:
Content-Type: application/json
Body:
{
"latitude": 52.899370,
"longitude": 5.804548,
"timestamp": 1449052628407
}
請求結果
通過請求,我得到以下結果:
{"latitude":null,"longitude":null,"lastActive":null}
這意味着 Spring 確實為我的UserLocation
類創建了一個新實例,但它沒有用主體中的數據填充它。
彈簧PUT方法
在 Spring 控制器中使用 PUT 方法時,實體不是立即更新嗎? 所以這意味着控制器中不會有額外的邏輯來更新實體,對嗎? (如果實體當然是可以更新的Hibernate/JPA模型)。
我似乎無法弄清楚問題所在。 有誰知道我做錯了什么?
更新
將@RequestBody
添加到我的控制器代碼中:
@RequestMapping(value = "/location/update/{id}", method = RequestMethod.PUT)
public UserLocation updateUserLocation(@PathVariable("id") int id, @RequestBody UserLocation user) {
return user;
}
讓我回到最初的問題( 不支持 415 媒體)。 添加此會引發 415 Media not supported 錯誤,我似乎無法修復。
固定的。 下面的解決方案
我在您的控制器中沒有看到 UserLocation 對象的 @RequestBody ? 還要確保你的屬性有 getter 和 setter。
public UserLocation updateUserLocation(@PathVariable("id") int id, UserLocation user) {
在執行 HTTP PUT 時,您將不得不放置額外的邏輯來將您的對象持久化到數據庫中。 你需要調用你的 DAO 或 Repository 來持久化你的對象。 通常,您將傳入的 UserLocation 對象映射到您保留的真實 JPA/Hibernate 實體。 這不會自動發生。
問題是您錯過了使用@RequestBody
注釋 UserLocation 參數
..updateUserLocation(@PathVariable("id") int id, @RequestBody UserLocation user)
還要確保為UserLocation
成員變量生成getters
和setters
。
我有同樣的問題。
@RestController
@RequestMapping("/api/task")
public class TaskController {
private Task task;
@RequestMapping(method=RequestMethod.GET)
public @ResponseBody Task getTasks() {
return task;
}
@RequestMapping(method=RequestMethod.POST)
public void addTask(Task task) {
System.out.println(task);
this.task = task;
}
}
POJO Class
public class Task implements Serializable{
private TaskStatus status = TaskStatus.IDLE;
private long duration;
public TaskStatus getStatus() {
return status;
}
public void setStatus(TaskStatus status) {
this.status = status;
}
public long getDuration() {
return duration;
}
public void setDuration(long duration) {
this.duration = duration;
}
public void decrementDuration() {
this.duration--;
}
public boolean isRunning() {
return this.status.equals(TaskStatus.RUNNING);
}
public String getName() {
return this.toString();
}
public void start() {
this.status = TaskStatus.RUNNING;
}
@Override
public String toString() {
return "Task [status=" + status + ", duration=" + duration + "]";
}
}
現在,當我輸入輸入
"duration": "120"
我收到輸出
Task [status=IDLE, duration=0`]
可以在輸出(setTask()的sysout)中看到收到的請求。
annotation. 為此,我也不得不刪除注釋。
但是,這沒有設置任何值。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.