Rainbow Engine

IT技術を分かりやすく簡潔にまとめることによる学習の効率化、また日常の気付きを記録に残すことを目指します。

GitHub Java

GitHubのWebAPIをコールしてユーザー情報を取得するサンプルプログラムの解説+エラー対応も2例紹介

投稿日:2020年7月16日 更新日:

(0)目次&概説

(1) 目的
 (1-1) 記事の目的
(2) APIの概要
 (2-1) APIとは?
 (2-2) Web APIとは?
 (2-3) Web APIの様々な呼び方
  (2-3-1) curlコマンドで呼び出し
  (2-3-2) JSP/Servletプログラムから呼び出し
(3) WebAPIコールの基本プログラム
 (3-1) ソースコード
(4) エラー対応
 (4-1) java.net.MalformedURLException: no protocol:
 (4-2) java.io.FileNotFoundException: [URL]

(1) 目的

(1-1) 記事の目的

APIを初めて使う方に向けて、GitHubのAPIの一つである「Users」をJava Servletプログラムからコールして、指定したユーザーのメタ情報を取得する際に行った手順を記録も兼ねて紹介します。
https://developer.github.com/v3/users/

目次にもどる

(2) APIの概要

(2-1) APIとは?

APIは”Application Programming Interface”の略で、サービスのデータや処理を外部に公開して利用してもらうためのインターフェイスです。APIを使う事によりアプリケーション間の接続を可能にするとともに、外部から自システムへはAPIを介してのみアクセスを許可する事で、データベースへの直接のアクセスや意図しないデータの書き換えを防ぎます。

目次にもどる

(2-2) Web APIとは?

APIの中でもクライアント/サーバ間でHTTP通信によりWeb経由で提供されるAPIをWebAPIと呼びます。WebAPIの代表的な出力形式(データ転送形式)はXML形式やJSON形式で、HTTPプロトコルベースのWebサーバによって処理されます。エンドポイントと呼ばれるURLを介してコールされ、引数などのパラメータを調整する事で結果を変化させます。
 

目次にもどる

(2-3) Web APIの様々な呼び方

前述の通りWebAPIはURLをベースに呼び出しを行うため、様々な方法での呼び出しが可能です。今回はその呼び出し方の例をいくつか紹介します。

(2-3-1) curlコマンドで呼び出し

curlとはコマンドラインツールで、コマンド実行によりネットワーク越しにリクエスト(Request)を作成できるコマンドです。URLを指定してAPI実行を行う事もでき、下記はその一例としてGitHubのユーザ情報を取得するURLを指定したAPIコールを照会します。

次のcurlコマンドの構文中の[Your GitHub User Name]にはご自身のGitHubユーザIDを入力します。
curl -u [Your GitHub User Name] https://api.github.com/user

実行するとJSON形式のレスポンスが返ってきます。

(図231)

↓JSON形式の応答が帰ってくる

目次にもどる

(2-3-2) JSP/Servletプログラムから呼び出し

当記事のメイントピックで2章以降で手順を解説します。最終的なアウトプットとしては、ブラウザからServletのURLを入力するとAPIコールが実行されて、画面上にその取得結果が表示されるようになります。

(図232)

目次にもどる

(3) WebAPIコールの基本プログラム

(3-1) ソースコード

この節ではGitHubのユーザー情報取得APIをJavaからコールした際のサンプルプログラムを紹介します。

package studyc;

package studyc;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.URL;
import java.net.URLConnection;
import java.util.Base64;

import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

/**
 * Servlet implementation class WebAPI_Test4
 */
@WebServlet("/WebAPI_Test4")
public class WebAPI_Test4 extends HttpServlet {
	private static final long serialVersionUID = 1L;
    public WebAPI_Test4() {
        super();
    }

	protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		String token = "6e83a69b5f9946971d3f2911ec113383e6c4ae56";
		String url = "api.github.com/users/XXXXXXXX";		
		response.getWriter().append("Served at: ").append(request.getContextPath());
		//getGithubContentUsingHttpClient(token,url);
		getGithubContentUsingURLConnection(request,response,token,url);
	}

	//### メソッド名称:	getGithubContentUsingURLConnection
	//### メソッド概要:	GitHubのAPI
	//### 	【引数3】String token	:WebAPIを利用するためのトークン
	//### 	【引数4】String url		:WebAPIのURL
	public static void getGithubContentUsingURLConnection(HttpServletRequest request, HttpServletResponse response, String token,String url) throws IOException {
		
		//### APIコールのためのURL組み立て
		String newURL = "https://" + url;
		
		//### InputStream型の変数を初期化
		InputStream crunchifyInStream = null;
		
		//### 変数の初期化
		String result = "";		//最終結果を格納するための変数
		String tmp = "";		//読み込んだデータを格納するための一時変数
		
		try {
			//### URLオブジェクトをインスタンス化
			//### 	【引数】newURL	:APIのURL
			URL myURL = new URL(newURL);
			
			//### URLクラスのopenConnection()メソッドを使って、URLConnectionクラスをインスタンス化
			URLConnection connection = myURL.openConnection();

			//### Base64.getEncoder()でBasic型のエンコーダの名称を取得(リクエストヘッダーにセット)
			//### 【参考1】https://docs.oracle.com/javase/8/docs/api/java/util/Base64.html
			String authString = "Basic " + Base64.getEncoder();
			
			//### setRequestProperty()メソッドでRequest(リクエスト)のプロパティ情報(リクエストヘッダー)をセットしています。
			//###	【参考1】https://docs.oracle.com/javase/7/docs/api/java/net/URLConnection.html
			//### 	【引数1】String key		:リクエストを表現するキーワード
			//### 	【引数2】String value	:付帯する値の情報
			connection.setRequestProperty("Authorization", authString);
			
			//### getInputStream()メソッドでURLConnectionクラスにてオープンしている接続から、データを読むInputStreamクラスのインスタンス作成
			//###	【参考1】https://docs.oracle.com/javase/7/docs/api/java/net/URLConnection.html
			crunchifyInStream = connection.getInputStream();
			
		} catch (Exception e) {
			e.printStackTrace();
		}
		//### InputStreamReaderクラスはByteストリームとCharacterストリームの橋渡しを行います。
		//### InputStreamReaderクラスのコンストラクタで引数を指定していないため、デフォルトの文字コードでインスタンス化しています。
		//### BufferedReaderクラスのコンストラクタを用いて、バッファリングによる最高効率の読込みを可能にしています(メモリアクセスによって読込みを行いディスクI/Oを削減する)
		BufferedReader in = new BufferedReader(new InputStreamReader(crunchifyInStream));
		
		//3.Parse the data
		try {
			//### 行がnullでない間、1行ずつ読んでいき、最終結果のresultに追加していく
			while((tmp = in.readLine())!=null) {
				result += tmp;
			}
			in.close();
		} catch (IOException e) {
			e.printStackTrace();
		}
		//### 画面出力
		//### 文字コードや出力形式の指定
		response.setContentType("text/html; charset=UTF-8");
		PrintWriter out = response.getWriter();
		//### 画面のHTMLに改行(<br />)を追記
		out.println("<br />");
		//### 画面に最終結果を表示
		response.getWriter().append(result);
	}
}

目次にもどる

(4) エラー対応

(4-1) java.net.MalformedURLException: no protocol:

(4-1-1) 発生状況

WebAPIをコールするServlet画面をブラウザから呼び出した際に下記エラーが発生。

エラーメッセージ例(※一部抜粋)

java.net.MalformedURLException: no protocol:
        at java.net.URL.(URL.java:593)
        at java.net.URL.(URL.java:490)
        at java.net.URL.(URL.java:439)
        at WebAPI_Test.getResult(WebAPI_Test.java:16)
        at WebAPI_Test.main(WebAPI_Test.java:10)

目次にもどる

(4-1-2) 原因

URLクラスのコンストラクタ「URL(String spec)」にて、引数に指定した文字列にプロトコル(例:http://やhttps://)が含まれていない場合、構文解析をした結果「java.net.MalformedURLException」エラーになっています。

(図411)

目次にもどる

(4-1-3) 対処

引数に与える文字列に正しい構文のURLを入力する事で解消します。
下図の例では「https://api.github.com/users/:username」という形でhttpsプロトコルのURLを与えています(例では結果として別のエラーが発生してしまっていますが、当該エラーは解消)。

(図412)

目次にもどる

(4-2) java.io.FileNotFoundException: [URL]

(4-2-1) 発生状況
WebAPIをコールするServlet画面をブラウザから呼び出した際に下記エラーが発生。

エラーメッセージ例(※一部抜粋)

java.io.FileNotFoundException: https://api.github.com/users/:Tatsuya-Yazaki
        at sun.net.www.protocol.http.HttpURLConnection.getInputStream0(HttpURLConnection.java:1896)
        at sun.net.www.protocol.http.HttpURLConnection.getInputStream(HttpURLConnection.java:1498)
        at sun.net.www.protocol.https.HttpsURLConnectionImpl.getInputStream(HttpsURLConnectionImpl.java:268)
        at studyc.WebAPI_Test4.getGithubContentUsingURLConnection(WebAPI_Test4.java:60)
        at studyc.WebAPI_Test4.doGet(WebAPI_Test4.java:43)

目次にもどる

(4-2-2) 原因

原因は該当するデータが存在しないためです。上記は悲しいミスで「https://api.github.com/users/」の直後に不要なコロン「:」が入ってしまっているため、正しくデータを取得出来ていませんでした。

GitHubのAPIドキュメントには「GET /users/:username」のような例が書かれていたりするので、私は知らずにコロン「:」を残してusernameの所だけを変えるというミスをしていました。これで時間を取られてしまい非常に勿体なかったので、みなさまも同じ目に遭わない事を願って書いています。

(図422)

目次にもどる

(4-2-3) 対処

実際にコロン「:」を除いて実行したのが以下の図です。

(図423)正しく動作するとcurlコマンドと同じJSON形式の結果が返ってくる

目次にもどる

Adsense審査用広告コード


Adsense審査用広告コード


-GitHub, Java

執筆者:


comment

メールアドレスが公開されることはありません。 が付いている欄は必須項目です

関連記事

Javaのメソッドで複数の戻り値を返却する方法

<目次> (1) Javaのメソッドで複数の戻り値を返却する方法  (1-1) 同じ型の値を複数返却したい場合 ⇒ 配列やList   ◎ポイント   ◎サンプル  (1-2) 異なる型の関連する値を …

Javaのthisとは?コンストラクタで引数を与えている場合・メソッド引数に使われる場合もご紹介

<目次> (1) Javaのthisとは?コンストラクタに出現する場合やメソッド引数に使われる場合もご紹介  (1-1) thisとは?  (1-2) 用途1:自分自身を指定【重要】  (1-3) 用 …

TomcatにWARファイルをデプロイする方法

  <目次> (1) TomcatにWARファイルをデプロイする方法  (1-1) STEP1:WARファイルの準備  (1-2) STEP2:WARファイルをサーバ上に配備  (1-3) …

JSP/Servletでcsvをダウンロードする機能を作成する手順

<目次> (1) JSP/Servletでcsvをダウンロードする機能を作成する手順  (1-0) 実現方針  (1-1) STEP1:Servletの追記  (1-2) STEP2:JSPの追記   …

JavaのSpring Bootを使ってHello Worldのアプリケーションを作成する

  <目次> (1) JavaのSpring Bootを使ってHello Worldのアプリケーションを作成する  (1-1) はじめに(Spring Bootとは?)  (1-2) Spr …

  • English (United States)
  • 日本語
Top