Spring BootのRest APIのControllerクラスのメモ。
|
Spring BootのRest API用のControllerには、RestControllerアノテーションを付ける。
import org.springframework.web.bind.annotation.RestController;
Rest APIの処理を行うメソッドは、レスポンスボディーを返す。
(ウェブアプリケーション用のControllerのメソッドは、次の処理(htmlの表示とか)を示すパスを返す)
Rest APIを扱うときは、依存ライブラリーにRest Repositories(spring-boot-starter-data-rest)を追加する。
〜
dependencies {
compile('org.springframework.boot:spring-boot-starter-data-rest')
compile('org.springframework.boot:spring-boot-starter-security')
compile('org.springframework.boot:spring-boot-starter-thymeleaf')
runtime('org.springframework.boot:spring-boot-devtools')
testCompile('org.springframework.boot:spring-boot-starter-test')
testCompile('org.springframework.security:spring-security-test')
}
「http://ホスト名:8080/api/example」(パスが「/api/example」)のリクエストに対して文字列を返す例。
package com.example.demo.rest; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMethod; import org.springframework.web.bind.annotation.RestController;
@RestController
public class ApiController {
@RequestMapping(path = "/api/example", method = RequestMethod.GET)
public String example() {
return "ok from example";
}
}
どのパスの処理を行うかについては@RequestMappingアノテーションで指定する。
メソッド名は自由に付けてよい。
戻り値はレスポンスボディーを返す。
Rest API用のControllerのメソッドの戻り値ではレスポンスボディーを返す。
戻り値の型がStringの場合、レスポンスボディーの内容をそのまま指定する。
@RestController
public class ApiController {
@RequestMapping(path = "/api/example", method = RequestMethod.GET)
public String example() {
return "ok from example";
}
}
↓
$ curl http://127.0.0.1:8080/api/example -X GET -u hishidama:hoge ok from example
メソッドからJavaBeanを返すと、JSONに変換される。
@RestController
public class ApiController {
public static class ExampleBean {
public String value1;
public String value2;
}
@RequestMapping(path = "/api/example2", method = RequestMethod.GET)
public ExampleBean example2() {
ExampleBean bean = new ExampleBean();
bean.value1 = "foo";
bean.value2 = "bar";
return bean;
}
}
↓
$ curl http://127.0.0.1:8080/api/example2 -X GET -u hishidama:hoge
{"value1":"foo","value2":"bar"}
ファイルをダウンロードさせる(クライアントにファイルの内容を返す)にはFileSystemResourceを使うのが便利。[2017-09-13]
参考: tag1216さんのSpring MVCのコントローラでの戻り値いろいろ
import java.io.File; import org.springframework.core.io.FileSystemResource; import org.springframework.core.io.Resource; import org.springframework.http.MediaType; import org.springframework.web.bind.annotation.RequestMapping;
@RequestMapping(path = "/api/download", produces = MediaType.TEXT_PLAIN_VALUE)
public Resource download() {
return new FileSystemResource(new File("D:/temp/t.txt"));
}
HTTPレスポンスに直接書き込む方法もあるそうだ。
import java.io.IOException; import java.nio.file.Files; import java.nio.file.Path; import java.nio.file.Paths; import javax.servlet.http.HttpServletResponse; import org.springframework.http.MediaType; import org.springframework.web.bind.annotation.RequestMapping;
@RequestMapping(path = "/api/download")
public void download(HttpServletResponse response) throws IOException {
Path path = Paths.get("D:/temp/t.txt");
response.setContentLengthLong(Files.size(path));
response.setContentType(MediaType.TEXT_PLAIN_VALUE);
Files.copy(path, response.getOutputStream());
}
リクエストボディーがJSONのとき、メソッドの引数に@RequestBodyアノテーションを付けてJSONを受け取るJavaBeanを指定すると、リクエストボディーの内容をJavaBeanで受け取ることが出来る。
@RestController
public class ApiController {
public static class ExampleBean {
public String value1;
public String value2;
}
@RequestMapping(path = "/api/example3", method = RequestMethod.POST)
public String example3(@RequestBody ExampleBean bean) {
〜
return "ok3";
}
}
↓
$ curl http://127.0.0.1:8080/api/example3 -u hishidama:hoge -X POST -H 'Content-Type: application/json' -d '{ "value1":"aaa", "value2":"bbb" }'
ok3
UNIXのcurlコマンドでは、-dでリクエストボディーを指定する。
以下のようなエラーが出るときは、-HでコンテンツタイプにJSONを指定する。
$ curl http://127.0.0.1:8080/api/example3 -u hishidama:hoge -X POST -d '{ "value1:"aaa", "valu2":"bbb" }'
{"timestamp":1504009473016,"status":415,"error":"Unsupported Media Type","exception":"org.springframework.web.HttpMediaTypeNotSupportedException","message":"Content type 'application/x-www-form-urlencoded;charset=UTF-8' not supported","path":"/api/example3"}
リクエストボディーをファイルで指定したい場合は、ファイル名の前に「@」を付ける。
$ echo '{ "value1":"aaa", "value2":"bbb" }' > example.json
$ curl http://127.0.0.1:8080/api/example3 -u hishidama:hoge -X POST -H 'Content-Type: application/json' -d @example.json