チェック処理を追加したRest APIサービスは、Spring Bootを利用したアプリケーションで呼び出し、エラー時のレスポンスを取得することができる。
今回は、STS(Spring Tool Suite)を利用したSpring Bootアプリケーション上で、特定のテーブルのデータ追加・更新を行う際にチェック処理を行うRest APIサービスを呼び出し、エラー時のレスポンスを取得してみたので、そのサンプルプログラムを共有する。
前提条件
下記記事の実装がそれぞれ完了していること。
作成したサンプルプログラムの内容
作成したサンプルプログラムの構成は以下の通り。
なお、上記の赤枠は、前提条件のdemoRestApiCallプロジェクトのプログラムから追加・変更したプログラムである。
Rest APIでデータ追加・更新時にチェックエラーになる処理の呼び出しを実行するサービスクラスの内容は以下の通りで、各種エラーになった場合の戻り値をDemoExceptionResponseクラスで取得している。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 | 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クラスと同じ項目を定義している。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 | 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オブジェクトを追加している。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 | 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でデータ追加・更新時にチェックエラーになる処理の呼び出しを実行するサービスクラスを呼び出している。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 | 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を利用したアプリケーションで呼び出し、エラー時のレスポンスを取得することができる。