@RequestBody をつけたら request body is missing のエラーになった

POST メソッドを受け付ける Controller に @RequestBody を付与した際に、タイトルの通りのエラーに遭遇したためメモ。

2021-01-20 03:05:42.522  WARN 2842 --- [nio-8081-exec-2] .w.s.m.s.DefaultHandlerExceptionResolver : Resolved [org.springframework.http.converter.HttpMessageNotReadableException: Required request body is missing: public org.springframework.http.ResponseEntity<com.kiyotakeshi.todo.entity.Todo> com.kiyotakeshi.todo.controller.TodoController.createTodo(com.kiyotakeshi.todo.entity.Todo)]

原因としては、 json ではない、あやまったリクエストを送っていたため。

f:id:ponkan1219:20210120032122p:plain

curl --location --request POST 'http://localhost:8081/todo/?activityName=test&color=black&category=test'

正しいリクエストは以下の形式。postman で作ったものを curl としてコピー。

f:id:ponkan1219:20210120032152p:plain

curl -i --location --request POST 'http://localhost:8081/todo/' \
--header 'Content-Type: application/json' \
--data-raw '{
    "activityName":"test",
    "color":"black",
    "category":"test"
}'

debugger で止めて、 Evaluate Expression すると、しっかりとオブジェクトに値が入っていることがわかる。

f:id:ponkan1219:20210120032208p:plain

以下がレスポンス、正常に作成された。

HTTP/1.1 201
Location: /todo/10012
Content-Type: application/json
Transfer-Encoding: chunked
Date: Tue, 19 Jan 2021 17:50:34 GMT

{"id":10012,"activityName":"test","color":"black","category":"test"}

ちなみに、レスポンスが json で返ってきているのは、Controller に付与している @RestController に、

@RestController
public class TodoController {
}

@ResponseBody が付与されているため。

※ちなみに @Controller (ステレオタイプアノテーション)がついてるから、 Component Scan され Bean化されてる

// org/springframework/web/bind/annotation/RestController.java
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Controller
@ResponseBody
public @interface RestController {
    (略)
}

そんな感じで、APIjson でリクエストを受けて、 json を返すものということがわかった。

参考にした stack overflow