1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

SpringBoot Controllerの引数 アノテーションをまとめたかった

Last updated at Posted at 2025-03-20

Controller書くときに「どうやってデータ受け取ればいいんだっけ」と悩むのでまとめておく
いつも既存コードコピペじゃまずいので動作確認

SpringBoot3.3.1 で動作確認

前提として知っとくといいこと

「リクエストパラメータ」についておさらい

  • GET
    • GET /book?id=2&title=sampleBook
    • ?の後ろに書いていくやつ
    • 「URLパラメータ」「クエリパラメータ」呼び方が安定してない気がする
    • 基本的に参照型に使う
    • データ長制限あり。長い文字列を扱うときは注意
  • POST
    • POST /addBook id=2 author=John
    • パラメータは「リクエストボディ」に記載
      • curlコマンドの-d
    • 更新系に使う
    • 文字数制限なし
    • Jsonとの相性がいい
  • PUT,DELETE,その他もろもろは無視

実際のところ

  • aタグ
    • GET
  • formタグによるsubmit
    • GET,POST選べる
    • POSTの場合はContent-Type:application/x-www-form-urlencoded@RequestBodyでは受け取れない
  • JSのfetch関数
    • GET,POST選べるけど
    • jsonと連携できるこれが強い
fetch("/submit", {
    method: "POST",
    headers: {
        "Content-Type": "application/json"
    },
    body: JSON.stringify({ username: "testuser", age: 25 })
});
  • ちょっと古いがJqueryのajax関数
    • GET,POST選べる
    • POST,dataを使う場合はContnet-Type:application/x-www-form-urlencodedとなる
$.ajax({
  url: "/api/data",
  method: "POST",
  data: {
    username: "John",
    age: 30
  }
});

結論

アノテーション GET POST 説明
@RequestParam クエリパラメータ (?key=value) やフォームの application/x-www-form-urlencoded を取得
@PathVariable URL のパスパラメータ (/users/{id}) を取得
@RequestBody × JSON データをリクエストボディから取得 (application/json)
@ModelAttribute フォームの application/x-www-form-urlencoded を DTO にマッピング
  • モダンなAPIはjsonでやりとりする(偏見)ので、@RequestBodyが柔軟で優秀
    • しかし、GETで使えないというデメリットあり
    • ただやっぱりJson連携は超絶便利なので実は全部POSTで受けるってのもありなのでは?
    • フロントエンドなにもわからん
  • GETの場合は随時適切なアノテーションを選択する

@RequestParam

@GetMapping("/book")
public String getBook(@RequestParam(name = "title", required = false) String title) {
    // クエリパラメータから受け取ったデータを処理します
    return "Book title: " + title;
}

URLパラメータを受け取るやつ
curlで叩くには

curl -X GET "http://localhost:8080/book?title=SampleBook"

(name = "title")をつけないと以下エラー
java.lang.IllegalArgumentException: Name for argument of type [java.lang.String] not specified, and parameter name information not available via reflection. Ensure that the compiler uses the '-parameters flag

名前を明示的につけなくても問題ないんじゃなかった?と思ったけどSpring Framework 6.1以降は明示しないとダメらしい
https://qiita.com/mitecha/items/a95546652c13cf041f54

requiredはデフォルトtrue

引数の型もいい感じにバインドしてくれる

@GetMapping("/book")
public String getBook(
    @RequestParam(name="title", required = false) String title, 
    @RequestParam(name = "id") int id,
    @RequestParam(name = "available") boolean available,
    @RequestParam(name = "tags") List<String> tags,
    @RequestParam(name = "publishedDate") @DateTimeFormat(iso = DateTimeFormat.ISO.DATE) LocalDate publishedDate
    ) {
    // クエリパラメータから受け取ったデータを処理します
    return String.format(
        "Book title: %s\nBook ID: %d\nAvailable: %b\nTags: %s\nPublished date: %s",
        title, id, available, String.join(", ", tags), publishedDate
    );
}

curl -X GET "http://localhost:8080/book?title=Sample+Book&id=1&available=true&tags=fiction&tags=adventure&publishedDate=2025-03-18"

Listは2回指定
日付型も柔軟に受け入れできる

当然カスタムクラスもいける

@GetMapping("/filter")
public String filterBooks(BookFilter filter) {
    // カスタムクラスから受け取ったデータを処理します
    return "Filtering books by genre: " + filter.getGenre() + ", author: " + filter.getAuthor();
}

//カスタムクラスの定義
public class BookFilter {
    private String genre;
    private String author;

    // ゲッターとセッター
}

curl -X GET "http://localhost:8080/filter?genre=fiction&author=John+Doe"

やりたいことはだいたいできる
べんり

@PathVariable

@GetMapping("/book/{id}")
public String getBookById(@PathVariable(name = "id") int id) {
    // idから本を取得する処理
    return "Book id: " + id;
}
curl -X GET "http://localhost:8080/book/2"

パスパラメータを受け取りたいときに使う
性質上IDなどを受け取りがち

カスタムクラスと両立することもあるけど、基本はIDなどの識別子だけ@PathVariableをつけるのが一般的か

@GetMapping("/book/details/{id}")
public String getBookDetails(@PathVariable(name = "id") int id, BookFilter filter) {
    return String.format("Book ID: %d, Genre: %s, Author: %s", id, filter.getGenre(), filter.getAuthor());
}

curl -X GET "http://localhost:8080/book/details/123?genre=fiction&author=JohnDoe"

フィルター部分はクエリパラメータで指定する

@ModelAttribute

基本的に複雑なデータを受け取りたいときに使う
渡したいパラメータが多い!→クラス(Model)にまとめよう→ModelAttribute使おう
GET,POSTは問わない

// GET
@GetMapping("/book/model/details")
public String getBookDetailsByModelGet(@ModelAttribute BookFilter filter) {
    // フィルターから本の詳細を取得する処理
    return String.format("Get! Genre: %s, Author: %s", filter.getGenre(), filter.getAuthor());
}

// POST
@PostMapping("/book/model/details")
public String getBookDetailsByModelPost(@ModelAttribute BookFilter filter) {
    // フィルターから本の詳細を取得する処理
    return String.format("Post! Genre: %s, Author: %s", filter.getGenre(), filter.getAuthor());
}

//GETにリクエスト
curl -X GET "http://localhost:8080/book/model/details?genre=fiction&author=JohnDoe"

//POSTにリクエスト
curl -X POST -d "genre=fiction&author=JohnDoe" "http://localhost:8080/book/model/details"

@RequestBody

APIつくるときは基本これ
jsonを受け取るときはこれでいい
基本的には引数はカスタムクラス1つにピチッとまとめて使いがち
どうせjsonだしまとめたほうがええやんみたいな考え


@PostMapping("/books")
public String createBook(@RequestBody BookRequest bookRequest) {
    // ここで受け取ったデータを処理
    return String.format(
        "Book received: %s\nBook ID: %d\nAvailable: %b\nTags: %s\nPublished date: %s",
        bookRequest.getTitle(), bookRequest.getId(), bookRequest.isAvailable(), String.join(", ", bookRequest.getTags()), bookRequest.getPublishedDate()
    );
}
curl -X POST http://localhost:8080/addBook -H "Content-Type: application/json" -d '{
    "title": "New Book",
    "available": true,
    "tags": ["fiction", "adventure"],
    "publishedDate": "2025-03-18"
}'

と思ったらこういうパターンもあった
@PathVariableで変更値対象のidを取得
@RequestBodyで変更内容データを取得

@PostMapping("/updateBook/{id}")
public String updateBook(@PathVariable(name = "id") int id, @RequestBody BookRequest bookRequest) {
    // ここで受け取ったデータを処理
    return String.format(
        "Book updated: %s\nAvailable: %b\nTags: %s\nPublished date: %s",
        bookRequest.getTitle(), bookRequest.isAvailable(), String.join(", ", bookRequest.getTags()), bookRequest.getPublishedDate()
    );
}
curl -X POST http://localhost:8080/updateBook/1 -H "Content-Type: application/json" -d '{
    "title": "Updated Book",
    "available": true,
    "tags": ["fiction", "adventure"],
    "publishedDate": "2025-03-18"
}'

参考

プロになるためのSpring入門――ゼロからの開発力養成講座
[改訂新版]プロになるためのWeb技術入門
Spring徹底入門 第2版 Spring FrameworkによるJavaアプリケーション開発

1
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?