以前このブログで紹介した、特定のテーブルのデータ取得・追加・更新・削除を行うRest APIサービスは、Spring Bootを利用したアプリケーションで呼び出すことができる。
今回は、STS(Spring Tool Suite)を利用したSpring Bootアプリケーション上で、特定のテーブルのデータ取得・追加・更新・削除を行うRest APIサービスを呼び出してみたので、そのサンプルプログラムを共有する。
前提条件
下記記事の実装が完了していること。
サンプルプログラムの作成
今回はSTS(Spring Tool Suite)上で、Spring Bootアプリケーションを作成するところから開始する。その手順は、以下の通り。
1) STSを起動し、「ファイル」の「新規」メニューから「Spring スターター・プロジェクト」を選択する。
2) プロジェクト名やグループ・パッケージ等を指定し、「次へ」ボタンを押下する。
3) 必要なライブラリを選択し、「完了」ボタンを押下する。今回は、DevTools・Lombok・Spring Webが必要なので、これらを選択している。
4) プロジェクトが作成でき、以下のようなフォルダ構成になる。
5) 作成されたプロジェクトの、pom.xmlの内容は、以下の通り。
<?xml version="1.0" encoding="UTF-8"?> <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>2.6.4</version> <relativePath/> <!-- lookup parent from repository --> </parent> <groupId>com.example.demo</groupId> <artifactId>demoRestApiCall</artifactId> <version>0.0.1-SNAPSHOT</version> <name>demoRestApiCall</name> <description>Demo Api Project for Spring Boot</description> <properties> <java.version>1.8</java.version> </properties> <dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-devtools</artifactId> <scope>runtime</scope> <optional>true</optional> </dependency> <dependency> <groupId>org.projectlombok</groupId> <artifactId>lombok</artifactId> <optional>true</optional> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-test</artifactId> <scope>test</scope> </dependency> </dependencies> <build> <plugins> <plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> <configuration> <excludes> <exclude> <groupId>org.projectlombok</groupId> <artifactId>lombok</artifactId> </exclude> </excludes> </configuration> </plugin> </plugins> </build> </project>
6) 上記プロジェクトの内容に、以下の赤枠のソースコードを追加・変更する。
application.propertiesの内容は以下の通りで、Spring Bootアプリケーションを起動するポート番号と、デバッグログを出力するための設定を定義している。
# ポート番号:8084で起動するよう設定 server.port = 8084 # デバッグログを出力するための設定 logging.level.com.example.demo = DEBUG
Spring Bootのメインクラスの内容は以下の通りで、Rest APIの各種呼び出しを実行するサービスクラスを呼び出す処理を追加している。
package com.example.demo; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.CommandLineRunner; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; @SpringBootApplication public class DemoRestApiCallApplication implements CommandLineRunner { /** Rest APIの各種呼び出しを実行するサービスクラス */ @Autowired private DemoRestApiCallService demoRestApiCallService; public static void main(String[] args) { SpringApplication.run(DemoRestApiCallApplication.class, args); } @Override public void run(String... args) throws Exception { // Rest APIの各種呼び出しを実行するメソッドを呼び出す demoRestApiCallService.execRestApi(); } }
Rest APIの各種呼び出しを実行するサービスクラスの内容は以下の通りで、USER_DATAテーブルのデータ取得・追加・更新・削除を行うRest APIサービスを呼び出している。
package com.example.demo; import java.util.List; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.core.ParameterizedTypeReference; import org.springframework.http.HttpEntity; import org.springframework.http.HttpHeaders; import org.springframework.http.HttpMethod; import org.springframework.http.ResponseEntity; import org.springframework.stereotype.Service; import org.springframework.web.client.RestTemplate; @Service public class DemoRestApiCallService { /** 全てのユーザーデータを取得するURL */ private static final String GET_ALL_USERS = "http://localhost:8085/users"; /** id=1のユーザーデータを取得するURL */ private static final String GET_USER_1 = "http://localhost:8085/users/1"; /** id=4のユーザーデータを取得するURL */ private static final String GET_USER_4 = "http://localhost:8085/users/4"; /** id=10のユーザーデータを取得するURL */ private static final String GET_USER_10 = "http://localhost:8085/users/10"; /** id=aのユーザーデータを取得するURL */ private static final String GET_USER_a = "http://localhost:8085/users/a"; /** ユーザーデータを追加するURL */ private static final String POST_USER = "http://localhost:8085/users"; /** id=4のユーザーデータを更新するURL */ private static final String PUT_USER_4 = "http://localhost:8085/users/4"; /** id=4のユーザーデータを削除するURL */ private static final String DELETE_USER_4 = "http://localhost:8085/users/4"; /** RestTemplateオブジェクト */ @Autowired private RestTemplate restTemplate; /** HttpHeadersオブジェクト */ @Autowired private HttpHeaders httpHeaders; /** ログ出力のためのクラス */ private static Log log = LogFactory.getLog(DemoRestApiCallService.class); /** * Rest APIの各種呼び出しを実行する. */ public void execRestApi() { log.debug("*** USER_DATAテーブルから全データを取得した結果 ***"); // user_dataテーブルのデータを全件取得 ResponseEntity<List<UserData>> responseList = restTemplate.exchange( GET_ALL_USERS, HttpMethod.GET, new HttpEntity<>(httpHeaders) , new ParameterizedTypeReference<List<UserData>>() {}); List<UserData> userDataList = responseList.getBody(); printUserDataList(userDataList); log.debug(""); log.debug("*** USER_DATAテーブルから特定のidをもつデータを取得した結果 ***"); // user_dataテーブルで、id=1であるデータを取得 ResponseEntity<UserData> response1 = restTemplate.exchange( GET_USER_1, HttpMethod.GET, new HttpEntity<>(httpHeaders) , UserData.class); UserData userData1 = response1.getBody(); log.debug("id=1であるuser_dataテーブルの値: " + userData1); // user_dataテーブルで、id=10(存在しないデータ)を取得 ResponseEntity<UserData> response10 = restTemplate.exchange( GET_USER_10, HttpMethod.GET, new HttpEntity<>(httpHeaders) , UserData.class); UserData userData10 = response10.getBody(); log.debug("id=10であるuser_dataテーブルの値: " + userData10); log.debug(""); log.debug("*** USER_DATAテーブルにid=4のデータを追加した結果 ***"); // user_dataテーブルに、id=4であるデータを追加 UserData newUserData = new UserData(4, "テスト プリン4", 2014, 10, 11, "1", "テスト4"); ResponseEntity<UserData> responseAdd = restTemplate.exchange( POST_USER, HttpMethod.POST, new HttpEntity<>(newUserData, httpHeaders) , UserData.class); UserData addUser = responseAdd.getBody(); log.debug("追加されたuser_dataテーブルの値: " + addUser); // user_dataテーブルで、追加されたデータを出力 printUserData4(); log.debug("*** USER_DATAテーブルのid=4のデータを更新した結果 ***"); // user_dataテーブルの、id=4であるデータを更新 UserData updUserData = new UserData(0, "テスト プリン4更新後", 2015, 11, 12, "2", "テスト4更新後"); ResponseEntity<UserData> responseUpd = restTemplate.exchange( PUT_USER_4, HttpMethod.PUT, new HttpEntity<>(updUserData, httpHeaders) , UserData.class); UserData updUser = responseUpd.getBody(); log.debug("更新されたuser_dataテーブルの値: " + updUser); // user_dataテーブルで、更新されたデータを出力 printUserData4(); log.debug("*** USER_DATAテーブルのid=4のデータを削除した結果 ***"); // user_dataテーブルの、id=4であるデータを削除 restTemplate.exchange(DELETE_USER_4, HttpMethod.DELETE , new HttpEntity<>(httpHeaders), Object.class); // user_dataテーブルで、削除されたデータを出力 printUserData4(); log.debug("*** USER_DATAテーブルから特定のidをもつデータを取得した結果(リクエストエラー時) ***"); // user_dataテーブルで、id=a(HTTPエラーになるデータ)を取得 try { restTemplate.exchange(GET_USER_a, HttpMethod.GET , new HttpEntity<>(httpHeaders), UserData.class); } catch(Exception ex) { log.error(ex); } } /** * 引数で指定されたユーザーデータリストを出力する. * @param userDataList ユーザーデータリスト */ private void printUserDataList(List<UserData> userDataList) { if(userDataList != null && !userDataList.isEmpty()) { for(UserData userData : userDataList) { log.debug(userData); } } } /** * USER_DATAテーブルで追加・更新・削除されたデータを出力する. */ private void printUserData4() { ResponseEntity<UserData> response4 = restTemplate.exchange( GET_USER_4, HttpMethod.GET, new HttpEntity<>(httpHeaders) , UserData.class); UserData userData4 = response4.getBody(); log.debug("id=4である、更新後のuser_dataテーブルの値: " + userData4); log.debug(""); } }
USER_DATAテーブルのデータを格納するためのエンティティクラスの内容は以下の通りで、Lombokを利用してコンストラクタやGetter/Setterメソッドを定義している。
package com.example.demo; import lombok.AllArgsConstructor; import lombok.Data; import lombok.NoArgsConstructor; // 「@Data」アノテーションを付与すると、このクラス内の全フィールドに対する // Getterメソッド・Setterメソッドにアクセスができる // 「@NoArgsConstructor」は、引数をもたないコンストラクタを生成するアノテーション // 「@AllArgsConstructor」は、全てのメンバを引数にもつコンストラクタを生成するアノテーション @Data @NoArgsConstructor @AllArgsConstructor public class UserData { /** ID */ private long id; /** 名前 */ private String name; /** 生年月日_年 */ private int birthY; /** 生年月日_月 */ private int birthM; /** 生年月日_日 */ private int birthD; /** 性別 */ private String sex; /** メモ */ private String memo; }
Beanオブジェクトを定義するクラスの内容は以下の通りで、Rest APIの各種呼び出しを実行するサービスクラスで参照するBeanオブジェクトを定義している。
package com.example.demo; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.http.HttpHeaders; import org.springframework.http.MediaType; import org.springframework.web.client.RestTemplate; @Configuration public class DemoConfigBean { /** * RestTemplateオブジェクトを作成する * @return RestTemplateオブジェクト */ @Bean public RestTemplate getRestTemplate() { return new RestTemplate(); } /** * ContentType:JSONであるHttpHeadersオブジェクトを作成する * @return HttpHeadersオブジェクト */ @Bean public HttpHeaders getHttpHeaders() { HttpHeaders headers = new HttpHeaders(); headers.setContentType(MediaType.APPLICATION_JSON); return headers; } }
これらのソースコード内容は、以下のサイトを参照のこと。
https://github.com/purin-it/java/tree/master/spring-boot-call-rest-api-crud/demoRestApiCall
サンプルプログラムの実行結果
Rest APIサービスのSpring Bootアプリケーションを起動後、今回作成したプロジェクトのSpring Bootアプリケーションを起動する。その結果出力されたログの内容は以下の通りで、USER_DATAテーブルのデータ取得・追加・更新・削除が問題なく実施されることが確認できる。
要点まとめ
- Spring Bootを利用したアプリケーションにおいて、特定のテーブルのデータ取得・追加・更新・削除を行うRest APIサービスは、RestTemplateクラスを用いて呼び出すことができる。
- RestTemplateクラスを用いてAPIを呼び出す際、HTTP メソッドを指定するが、その際、データ取得時はHttpMethod.GET、データ追加時はHttpMethod.POST、データ更新時はHttpMethod.PUT、データ削除時はHttpMethod.DELETEをそれぞれ指定する。