Spring Boot API連携

Spring Bootでチェック処理を追加したRest APIサービスを呼び出してみた

チェック処理を追加したRest APIサービスは、Spring Bootを利用したアプリケーションで呼び出し、エラー時のレスポンスを取得することができる。

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

前提条件

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

Spring BootのRest APIサービスにチェック処理を追加してみた特定のテーブルのデータ取得・追加・更新・削除を行うRest APIサービスでは、データ追加・更新する際は、@RequestBodyアノテ...
Spring Bootで特定のテーブルのデータ取得・追加・更新・削除を行うRest APIサービスを呼び出してみた以前このブログで紹介した、特定のテーブルのデータ取得・追加・更新・削除を行うRest APIサービスは、Spring Bootを利用した...

作成したサンプルプログラムの内容

作成したサンプルプログラムの構成は以下の通り。
サンプルプログラムの構成
なお、上記の赤枠は、前提条件のdemoRestApiCallプロジェクトのプログラムから追加・変更したプログラムである。

Rest APIでデータ追加・更新時にチェックエラーになる処理の呼び出しを実行するサービスクラスの内容は以下の通りで、各種エラーになった場合の戻り値をDemoExceptionResponseクラスで取得している。

package com.example.demo;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpEntity;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpMethod;
import org.springframework.stereotype.Service;
import org.springframework.web.client.HttpClientErrorException;
import org.springframework.web.client.RestTemplate;

import com.fasterxml.jackson.databind.ObjectMapper;

@Service
public class DemoRestApiCallCheckService {

    /** ユーザーデータを追加するURL */
    private static final String POST_USER = "http://localhost:8085/users";

    /** id=3のユーザーデータを更新するURL */
    private static final String PUT_USER_3 = "http://localhost:8085/users/3";

    /** RestTemplateオブジェクト */
    @Autowired
    private RestTemplate restTemplate;

    /** HttpHeadersオブジェクト */
    @Autowired
    private HttpHeaders httpHeaders;
    
    /** ObjectMapperオブジェクト */
    @Autowired
    private ObjectMapper objectMapper;

    /** ログ出力のためのクラス */
    private static Log log = LogFactory.getLog(DemoRestApiCallCheckService.class);

    /**
     * Rest APIでデータ追加・更新時にチェックエラーになる処理の呼び出しを実行する.
     */
    public void execRestApiCheck() {

        log.debug("*** USER_DATAテーブルに(名前の)チェックエラーとなるデータを" 
                + "追加しようとした結果 ***");    
        try {
            UserData newUserData = new UserData(4, "", 2012, 2, 25, "1", "テスト4");
            restTemplate.exchange(POST_USER, HttpMethod.POST
                , new HttpEntity<>(newUserData, httpHeaders), UserData.class);
            log.debug("(名前の)チェックエラーとなるため、この部分は通過しない");
        } catch (HttpClientErrorException ex) {
            try {
                DemoExceptionResponse demoExceptionResponse = objectMapper.readValue(
                        ex.getResponseBodyAsString(), DemoExceptionResponse.class);
                log.error("発生したエラーメッセージ : " 
                    + demoExceptionResponse.getMessage());
                log.debug("エラー時のレスポンス内容 : " + demoExceptionResponse);
                log.debug("");
            } catch (Exception ex2) {
                log.error(ex2);
                return;
            }
        }
        
        log.debug("*** USER_DATAテーブルに(生年月日の)チェックエラーとなるデータを" 
                + "追加しようとした結果 ***");    
        try {
            UserData newUserData = new UserData(4, "テスト プリン4", 2012, 2, 30
                                              , "1", "テスト4");
            restTemplate.exchange(POST_USER, HttpMethod.POST
                , new HttpEntity<>(newUserData, httpHeaders), UserData.class);
            log.debug("(生年月日の)チェックエラーとなるため、この部分は通過しない");
        } catch (HttpClientErrorException ex) {
            try {
                DemoExceptionResponse demoExceptionResponse = objectMapper.readValue(
                        ex.getResponseBodyAsString(), DemoExceptionResponse.class);
                log.error("発生したエラーメッセージ : " 
                    + demoExceptionResponse.getMessage());
                log.debug("エラー時のレスポンス内容 : " + demoExceptionResponse);
                log.debug("");
            } catch (Exception ex2) {
                log.error(ex2);
                return;
            }
        }
        
        log.debug("*** USER_DATAテーブルに(性別の)チェックエラーとなるデータを" 
                + "追加しようとした結果 ***");    
        try {
            UserData newUserData = new UserData(4, "テスト プリン4", 2012, 2, 25
                , "3", "テスト4");
            restTemplate.exchange(POST_USER, HttpMethod.POST
                , new HttpEntity<>(newUserData, httpHeaders), UserData.class);
            log.debug("(性別の)チェックエラーとなるため、この部分は通過しない");
        } catch (HttpClientErrorException ex) {
            try {
                DemoExceptionResponse demoExceptionResponse = objectMapper.readValue(
                        ex.getResponseBodyAsString(), DemoExceptionResponse.class);
                log.error("発生したエラーメッセージ : " 
                    + demoExceptionResponse.getMessage());
                log.debug("エラー時のレスポンス内容 : " + demoExceptionResponse);
                log.debug("");
            } catch (Exception ex2) {
                log.error(ex2);
                return;
            }
        }
        
        log.debug("*** USER_DATAテーブルに(名前・生年月日・性別の)チェックエラーと" 
                + "なるデータを追加しようとした結果 ***");    
        try {
            UserData newUserData = new UserData(4, "", 2012, 2, 30, "3", "テスト4");
            restTemplate.exchange(POST_USER, HttpMethod.POST
                , new HttpEntity<>(newUserData, httpHeaders), UserData.class);
            log.debug("(名前・生年月日・性別の)チェックエラーとなるため、この部分は通過しない");
        } catch (HttpClientErrorException ex) {
            try {
                DemoExceptionResponse demoExceptionResponse = objectMapper.readValue(
                        ex.getResponseBodyAsString(), DemoExceptionResponse.class);
                log.error("発生したエラーメッセージ : " 
                    + demoExceptionResponse.getMessage());
                log.debug("エラー時のレスポンス内容 : " + demoExceptionResponse);
                log.debug("");
            } catch (Exception ex2) {
                log.error(ex2);
                return;
            }
        }
        
        log.debug("*** USER_DATAテーブルに(名前・生年月日・性別の)チェックエラーと" 
                + "なるデータを更新しようとした結果 ***");    
        try {
            UserData updUserData = new UserData(0, "", 2012, 2, 30, "3", "テスト4");
            restTemplate.exchange(PUT_USER_3, HttpMethod.PUT
                , new HttpEntity<>(updUserData, httpHeaders), UserData.class);
            log.debug("(名前・生年月日・性別の)チェックエラーとなるため、この部分は通過しない");
        } catch (HttpClientErrorException ex) {
            try {
                DemoExceptionResponse demoExceptionResponse = objectMapper.readValue(
                        ex.getResponseBodyAsString(), DemoExceptionResponse.class);
                log.error("発生したエラーメッセージ : " 
                    + demoExceptionResponse.getMessage());
                log.debug("エラー時のレスポンス内容 : " + demoExceptionResponse);
                log.debug("");
            } catch (Exception ex2) {
                log.error(ex2);
                return;
            }
        }
    }
}



また、各種エラーになった場合の戻り値を定義するクラスの内容は以下の通りで、前提条件のdemoRestApiプロジェクトのDemoExceptionResponseクラスと同じ項目を定義している。

package com.example.demo;

import java.util.Date;

import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;

//「@Data」アノテーションを付与すると、このクラス内の全フィールドに対する
//Getterメソッド・Setterメソッドにアクセスができる
//「@NoArgsConstructor」は、引数をもたないコンストラクタを生成するアノテーション
//「@AllArgsConstructor」は、全てのメンバを引数にもつコンストラクタを生成するアノテーション
@Data
@NoArgsConstructor
@AllArgsConstructor
public class DemoExceptionResponse {
    
    /** メッセージ */
    private String message;
    
    /** メッセージ詳細 */
    private String details;
    
    /** 発生日時 */
    private Date timestamp;

}

さらに、Beanオブジェクトを定義するクラスの内容は以下の通りで、ObjectMapperクラスの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;

import com.fasterxml.jackson.databind.ObjectMapper;

@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;
    }
    
    /**
     * ObjectMapperオブジェクトを作成する
     * @return ObjectMapperオブジェクト
     */
    @Bean
    public ObjectMapper getObjectMapper() {
        return new ObjectMapper();
    }
}

また、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 DemoRestApiCallCheckService demoRestApiCallCheckService;
    
    public static void main(String[] args) {
        SpringApplication.run(DemoRestApiCallApplication.class, args);
    }

    @Override
    public void run(String... args) throws Exception {
        // Rest APIでデータ追加・更新時にチェックエラーになる処理を呼び出す
        demoRestApiCallCheckService.execRestApiCheck();
    }

}

その他のソースコード内容は、以下のサイトを参照のこと。
https://github.com/purin-it/java/tree/master/spring-boot-call-rest-api-check/demoRestApiCall



「AOMEI Partition Assistant Standard(無料)版」は便利なパーティション管理ツールだったハードディスクの記憶領域を論理的に分割し、分割された個々の領域のことを、パーティションといいます。 例えば、以下の図の場合、C/D...

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

Rest APIサービスのSpring Bootアプリケーションを起動後、今回作成したプロジェクトのSpring Bootアプリケーションを起動する。その結果出力されたログの内容は以下の通りで、エラー時のメッセージやレスポンスが想定通りに取得できていることが確認できる。
サンプルプログラムの実行結果

要点まとめ

  • チェック処理を追加したRest APIサービスは、Spring Bootを利用したアプリケーションで呼び出し、エラー時のレスポンスを取得することができる。