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