チェック処理を追加したRest APIサービスは、Spring Bootを利用したアプリケーションで呼び出し、エラー時のレスポンスを取得することができる。
今回は、STS(Spring Tool Suite)を利用したSpring Bootアプリケーション上で、特定のテーブルのデータ追加・更新を行う際にチェック処理を行うRest APIサービスを呼び出し、エラー時のレスポンスを取得してみたので、そのサンプルプログラムを共有する。
前提条件
下記記事の実装がそれぞれ完了していること。
作成したサンプルプログラムの内容
作成したサンプルプログラムの構成は以下の通り。

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

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





