Spring の Web API で JSON 形式でデータを受け取る方法について
解決したいこと
Springでアプリを開発しているのですが、その中で非同期通信を使用したく最近学んだfetch関数でjsを実装しようと思いました。
下記のコードは実際に使用しているコードではなくchatGptに生成してもらったタスク管理アプリで特定のタスクの完了状態を更新するシナリオになります。
しかし、下記の書き方だとbad requestといわれてしまいます。なぜなのでしょうか?
問題のコード
function updateTaskStatus(taskId, isComplete) {
// リクエストデータの作成
let requestData = {
id: taskId, // 更新したいタスクのID
completed: isComplete // 完了かどうかの状態
};
// fetch関数でサーバーにPOSTリクエストを送信
fetch('/api/task/updateStatus', {
method: 'POST',
headers: {
'Content-Type': 'application/json', // JSON形式で送信する
},
body: JSON.stringify(requestData) // リクエストデータをJSONに変換して送信
})
.then(response => {
if (!response.ok) {
throw new Error('タスクの更新に失敗しました');
}
return response.json(); // JSONのレスポンスをパース
})
.then(data => {
console.log('タスクの状態が更新されました:', data); // 成功した場合の処理
})
.catch(error => {
console.error('更新エラー:', error); // エラーが発生した場合の処理
});
}
@RestController
@RequestMapping("/api/task")
public class TaskController {
@PostMapping("/updateStatus")
public ResponseEntity<String> updateTaskStatus(@RequestBody TaskUpdateRequest request) {
// リクエストからタスクIDと完了状態を取得
Integer taskId = request.getId();
Boolean isComplete = request.getCompleted();
// サービスでタスクの状態を更新する(仮の処理)
boolean success = taskService.updateTaskStatus(taskId, isComplete);
return ResponseEntity.ok("タスクの状態が正常に更新されました");
}
}
}
私が実際に書いたコードでは、@RequestBody Integer taskId,Boolean isCompleteのような形でしたがそれがだめっだったのでしょうか
(下記のコードだとうごきました)
function updateTaskStatus(taskId, isComplete) {
// FormDataオブジェクトの作成
let formData = new FormData();
formData.append('id', taskId); // 更新したいタスクのIDを追加
formData.append('completed', isComplete); // 完了かどうかの状態を追加
// fetch関数でサーバーにPOSTリクエストを送信
fetch('/api/task/updateStatus', {
method: 'POST',
body: formData // FormDataをリクエストボディに送信
})
.then(response => {
if (!response.ok) {
throw new Error('タスクの更新に失敗しました');
}
return response.json(); // JSONのレスポンスをパース
})
.then(data => {
console.log('タスクの状態が更新されました:', data); // 成功した場合の処理
})
.catch(error => {
console.error('更新エラー:', error); // エラーが発生した場合の処理
});
}
@RestController
@RequestMapping("/api/task")
public class TaskController {
@PostMapping("/updateStatus")
public ResponseEntity<String> updateTaskStatus(
@RequestParam("id") Integer taskId, // リクエストからタスクIDを取得
@RequestParam("completed") Boolean isComplete // リクエストから完了状態を取得
) {
// サービスでタスクの状態を更新する(仮の処理)
boolean success = taskService.updateTaskStatus(taskId, isComplete);
if (success) {
return ResponseEntity.ok("タスクの状態が正常に更新されました");
} else {
return ResponseEntity.status(HttpStatus.BAD_REQUEST).body("タスクの更新に失敗しました");
}
}
}
変更したこと
・元々、JavaScriptでfetch関数を使用してJSON形式でデータを送信していましたが、これをFormData形式に変更しました。
・コントローラーで受け取る引数のアノテーションを@RequestBodyから@RequestParamに変更しました。
質問まとめ
なぜJSON形式でデータを送信するとbad requestになるのか、JSON形式では書けないのか?という質問になります。
有識者の方がいましたらご教示いただけますと幸いです。