Spring Boot API連携

Spring Bootで特定のテーブルのデータ取得・追加・更新・削除を行うRest APIサービスを呼び出してみた

以前このブログで紹介した、特定のテーブルのデータ取得・追加・更新・削除を行うRest APIサービスは、Spring Bootを利用したアプリケーションで呼び出すことができる。

今回は、STS(Spring Tool Suite)を利用したSpring Bootアプリケーション上で、特定のテーブルのデータ取得・追加・更新・削除を行うRest APIサービスを呼び出してみたので、そのサンプルプログラムを共有する。

前提条件

下記記事の実装が完了していること。

Spring Bootで特定のテーブルのデータ取得・追加・更新・削除を行うRest APIサービスを作成してみたSpring Bootアプリケーションでは、@RestControllerアノテーションを利用することで、Rest APIサービスを作成...

サンプルプログラムの作成

今回はSTS(Spring Tool Suite)上で、Spring Bootアプリケーションを作成するところから開始する。その手順は、以下の通り。

1) STSを起動し、「ファイル」の「新規」メニューから「Spring スターター・プロジェクト」を選択する。
サンプルプログラムの作成_1

2) プロジェクト名やグループ・パッケージ等を指定し、「次へ」ボタンを押下する。
サンプルプログラムの作成_2

3) 必要なライブラリを選択し、「完了」ボタンを押下する。今回は、DevTools・Lombok・Spring Webが必要なので、これらを選択している。
サンプルプログラムの作成_3

4) プロジェクトが作成でき、以下のようなフォルダ構成になる。
サンプルプログラムの作成_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>



freelance hubを利用して10万件を超える案件情報からJava Spring案件を検索してみたfreelance hubは、レバテックフリーランスやフリエン(furien)を始めとした多くのフリーランスエージェントの案件をまとめて...

6) 上記プロジェクトの内容に、以下の赤枠のソースコードを追加・変更する。
サンプルプログラムの作成_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



「HD Video Converter Factory Pro」は動画の形式変換や編集・録画等を行える便利ツールだった動画の形式変換や編集・録画等を行える便利ツールの一つに、「HD Video Converter Factory Pro」があります。ここ...

サンプルプログラムの実行結果

Rest APIサービスのSpring Bootアプリケーションを起動後、今回作成したプロジェクトのSpring Bootアプリケーションを起動する。その結果出力されたログの内容は以下の通りで、USER_DATAテーブルのデータ取得・追加・更新・削除が問題なく実施されることが確認できる。
サンプルプログラムの実行結果_1

要点まとめ

  • Spring Bootを利用したアプリケーションにおいて、特定のテーブルのデータ取得・追加・更新・削除を行うRest APIサービスは、RestTemplateクラスを用いて呼び出すことができる。
  • RestTemplateクラスを用いてAPIを呼び出す際、HTTP メソッドを指定するが、その際、データ取得時はHttpMethod.GET、データ追加時はHttpMethod.POST、データ更新時はHttpMethod.PUT、データ削除時はHttpMethod.DELETEをそれぞれ指定する。