REST通信には、げきつよRestTemplateを使うべし
RestTemplate
RestTemplateって?
RestTemplateは、REST API(Web API)を呼び出すためのメソッドを提供するクラス。
Spring Frameworkが提供するHTTPクライアント(HttpClientをラップしている)。
まとめると、、、REST通信が簡単にできる便利部品。
DTOからJson形式のリクエストに変換する処理や、Json形式のレスポンスをDTOにバインドする処理をしてくれる。
データ形式はJson以外にXmlやFormなど様々対応していて、カスタマイズも可能!!
DTO => Json
@Getter // (1)
@Setter // (1)
public class SomeRequestResource {
private String message; // (2)
}
(1) ライブラリのlombock
を使用してGetter, Setterを自動生成
(2) Json変換を後に反映されるフィールド
{
"messsage": "test message"
}
DTOのフィールド名と値がJson形式に変換される
Json => DTO
{
"messsage": "test message"
}
@Getter
@Setter
public class SomeRequestResource {
private String message; // (1)
}
(1) Jsonの値がバインドされるフィールド
RestTemplate
の使い方
「きほん」のき
とりあえずインジェクション
@Service
public class XxxxServiceImpl implements XxxxService {
@Autowired
RestTemplate restTemplate;
// ...
}
今回のメインRestTemplate
をインジェクション。このRestTemplate
の中にREST通信に使うパーツがいっぱい詰まってる。
GET送信してみる
@Getter
@Setter
public class TestResponseResource {
private String id; // (1)
private String message; // (1)
}
(1) レスポンスをバインドするフィールド
@Service
public class XxxxServiceImpl implements XxxxService {
@Autowired
RestTemplate restTemplate;
public static final String URL = "http://com.example.rest/test";
public TestResponseResource getTestResponse() {
// (1)
return restTemplate.getForObject(URL, TestResponseResource.class);
}
}
(1) GET送信する。
(1) getForObject
の引数
引数順 | 型 | 説明 |
---|---|---|
1 | String |
送信先のURL |
2 | Class<T> |
送信先から返却されたResponseBody をバインドするクラス |
POST送信してみる
@Getter
@Setter
public class TestRequestResource {
private String message; // (1)
}
(1) 送信する値
@Getter
@Setter
public class TestResponseResource {
private String id; // (1)
private String message; // (1)
}
(1) レスポンスをバインドするフィールド
@Service
public class XxxxServiceImpl implements XxxxService {
@Autowired
RestTemplate restTemplate;
public static final String URL = "http://com.example.rest/test";
public TestResponseResource getTestResponse() {
// (1)
TestRequestResource request = new TestRequestResource();
request.setMessage("test message");
// (2)
return restTemplate.postForObject(URL,request,TestResponseResource.class);
}
}
(1) 送信データを設定する
(2) POST送信
(2) postForObject
の引数
引数順 | 型 | 説明 |
---|---|---|
1 | String |
送信先のURL |
2 | Object |
送信する値 |
3 | Class<T> |
送信先から返却されたResponseBody をバインドするクラス |
「きほん」のほ
送信URLを動的に変更する
REST通信の場合、URLからResourceのid
情報を取得する場合がある。
例) http://com.example.rest/book/1
RestTemplate
の場合、複数パターンで実装が可能。
順番にPathParameter
つめつめパターン
@Getter
@Setter
public class BookResponseResource {
private String id;
private String message;
}
@Service
public class XxxxServiceImpl implements XxxxService {
@Autowired
RestTemplate restTemplate;
// (1)
public static final String URL = "http://com.example.rest/book/{id}";
public TestResponseResource getTestResponse() {
// (2)
return restTemplate.getForObject(URL, BookResponseResource.class, "1");
}
}
(1) {id}
の箇所にパラメータがバインドされる
(2) 引数の最後にパラメータにバインドしたい文字列を渡す。可変長引数で取るため、複数指定可能。
明示的につめつめパターン
@Getter
@Setter
public class BookResponseResource {
private String id;
private String message;
}
@Service
public class XxxxServiceImpl implements XxxxService {
@Autowired
RestTemplate restTemplate;
// (1)
public static final String URL = "http://com.example.rest/book/{id}";
public BookResponseResource getTestResponse() {
// (2)
Map<String, String> params = new HashMap<String, String>();
params.put("id", "1");
// (3)
return restTemplate.getForObject(URL, BookResponseResource.class, params);
}
}
(1) {id}
の箇所にパラメータがバインドされる
(2) パラメータにバインドする値を設定
(2) 引数の最後にパラメータにバインドしたい値のMap<String, String>
を渡す。
送信するHeader情報を変更する
送信するデータ形式をXMLなどの変更した場合や、文字コードを変更した場合、特殊なHeaderを送信したい場合など臨機応変に変更可能。
Content-Type
を変更
Content-Type
のみを変更する場合
public BookResponseResource getTestResponse(BookRequestResource request) {
RequestEntity<BookRequestResource> requestEntity =
RequestEntity
.post(new URI(URL))
.contentType(MediaType.APPLICATION_XML) // (1)
.body(request);
return restTemplate.getForObject(requestEntity, BookResponseResource.class);
}
(1) Content-Type
を変更
charsetも変更する場合
public BookResponseResource getTestResponse(BookRequestResource request) {
// (1)
Map<String, String> prop = new HashMap<String, String>();
prop.put("charset", "shift_jis");
// (2)
MediaType mediaType = new MediaType(MediaType.APPLICATION_XML, param);
RequestEntity<BookRequestResource> requestEntity =
RequestEntity
.post(new URI(URL))
.contentType(mediaType)
.body(request);
return restTemplate.getForObject(requestEntity, BookResponseResource.class);
}
(1) MediaType
のプロパティ(charset
)を設定
(2) プロパティを元にMediaType
を生成
「きほん」のん
通信先でのエラーをハンドリングする
public TestResponseResource getTestResponse() {
// (1)
try {
return restTemplate.getForObject(URL, TestResponseResource.class);
}
catch (HttpClientErrorException e) { // (1)
logger.error("400系エラー発生");
throw e;
}
catch (HttpServerErrorException e) { // (2)
logger.error("500系エラー発生");
throw e;
}
}
(1) レスポンスのHttpStatusコードが400系の場合に発生する。
(2) レスポンスのHttpStatusコードが500系の場合に発生する。
Discussion