【Spring Boot】Controllerの基礎(REST API)
Controller クラスの作成
REST API 用の Controller クラスには、@RestControllerというアノテーションを付与します。
@RestController
public class SampleController {
//...
}REST API ではなく、テンプレートエンジンなどを使用する場合は@Controllerを付与します。
HTTP メソッド
Spring Boot では、HTTP メソッドに対応するアノテーションが用意されています。
| HTTP メソッド | アノテーション |
|---|---|
| GET | @GetMapping |
| POST | @PostMapping |
| PUT | @PutMapping |
| DELETE | @DeleteMapping |
メソッドに付与することで、そのメソッドの処理は HTTP メソッドに対応する処理となります。
@RestController
public class SampleController {
@GetMapping
public List<SampleData> findAll() {
//...
}
@PostMapping
public void create() {
//...
}
}パスの指定
パスの指定は、上記の HTTP メソッドに対するアノテーションの引数として指定します。
//GET http://localhost:8080/sample-data
@GetMapping("sample-data")
public List<SampleData> findAll() {
//....
}
//POST http://localhost:8080/sample-data
@PostMapping("sample-data")
public void create() {
//...
}Controller で共通のパスを指定するには、@RequestMappingをクラスに付与します。
@RestController
@RequestMapping
public class SampleController {
//GET http://localhost:8080/sample-data
@GetMapping
public List<SampleData> findAll() {
//...
}
//POST http://localhost:8080/sample-data
@PostMapping
public void create() {
}
}レスポンス
レスポンスとしてどのようなデータを返したいかは、メソッドの戻り値で決まります。
シンプルなテキストとして返したい場合は、Stringを戻り値とします。
JSON 形式で返したい場合は、対応するクラスを作成して戻り値とします。 このとき、JSON のプロパティはクラスのゲッターを基に設定されます。
- クラス
public class SampleData { private String id; private String firstName; private String lastName; private int age; public SampleData(String id, String firstName, String lastName String age) { this.id = id; this.firstName = firstName; this.lastName = lastName; this.age = age; } public String getId() { return id; } public String getName() { return firstName + " " + lastName; } public int getAge() { return age; } } - Controller
@GetMapping public SampleData getSampleData() { return new ("000001", "taro", "yamada", 20); } - レスポンス(JSON)
{ "id": "000001", "name": "taro yamada", "age": 20 }
リクエストパラメーターについて
リクエストにパラメーターを含める方法としては、以下の 3 つがあります。
クエリ
GET /sample-data?id=000001 HTTP/1.1URL の末尾にパラメーターを含める方法で、主に GET で使用します。
?以降にパラメーター名=値として定義します。複数ある場合は&で繋げます。
リクエストボディ
POST /sample-data HTTP/1.1
Content-Type: application/x-www-form-urlencoded
id=000001&firstName=taro&lastName=yamada&age=20POST /sample-data HTTP/1.1
Content-Type: application/json
{
"id": "000001",
"firstName": "taro",
"lastName": "yamada",
"age": 20
}リクエストボディにパラメーターを設定する方法で、GET 以外で使用します。
パラメーターのフォーマット(Content-Type)には、application/x-www-form-urlencodedとapplication/jsonが使用されます。
パス
GET /sample-data/000001 HTTP/1.1パスの一部をパラメーターとする方法で、GET と DELETE で使用します。
リクエストパラメーターの参照
@RequestParam
クエリパラメーターや、application/x-www-form-urlencodedとして送られる場合は、@RequestParamを使用します。
メソッドの引数にパラメーター名と同名の変数を定義し、@RequestParamを付与します。
@GetMapping
public SampleData findById(@RequestParam String id) {
//...
}
@PostMapping
public void create(@RequestParam String id, @RequestParam String firstName,
@RequestParam String lastName, @RequestParam int age) {
//...
}パラメーター名と変数名が異なる場合は、@RequestParam(name = "id") String fooIdのようにアノテーションの引数で指定します。
これらのパラメーターは必須となるため、指定されていない(null の)場合はMissingServletRequestParameterExceptionがスローされます。
必須でないパラメーターには、@RequestParam(required = false)として付与します。
また変数の型に変換できないパラメーターが渡された場合は、MethodArgumentTypeMismatchExceptionがスローされます。
DTO(Data Transfer Object)
@RequestParamによる指定方法では、1 つ 1 つパラメーターを定義しないといけないため、手間かつ見にくいものになってしまします。
これを解決するために、パラメーター名と同じ名前のフィールドにもつクラス(DTO)を作成します。 このときデフォルトコンストラクター(引数なしコンストラクター)とセッターを必ず作成してください。
public class SampleDataParam {
String id;
String firstName;
String lastName;
int age;
public SampleDataParam(){
}
}@RequestParamの指定の代わりに、DTO を指定します。
これにより、パラメーターと同名のフィールドに値が設定されたインスタンスが生成されます。
@PostMapping
public void create(SampleDataParam param) {
//...
}int 型フィールドに"abcde"のような型変換できないパラメーターが渡された場合は、
HttpMessageNotReadableExceptionがスローされます。
以下で説明しますが、引数にアノテーションを指定していない場合は、application/x-www-form-urlencodedで送信されたパラメーターが紐づきます。
@ModelAttribute
DTO にクエリパラメーターを紐づける場合は、@ModelAttributeを付与します。
@GetMapping
public SampleData get(@ModelAttribute SampleDataParam param) {
//...
}@RequestBody
application/jsonとしてパラメーターを受け取る場合は、DTO に@RequestBodyを付与します。
@PostMapping
public void create(@RequestBody SampleDataParam param) {
//...
}@PathValiable
パスパラメーターを使用する場合は、まずパスのどの部分がパラメーターであるかを定義します。
定義は{パラメーター名}と指定します。
次にパラメーター用の変数を引数に定義し、@PathValiableを付与します。
@GetMapping("{id}")
public SampleData findById(@PathValidable String id) {
//...
}