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

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

関連記事

JVMの基本アーキテクチャと各サブシステム等の概要説明について

(0)目次&概説 (1) 記事の目的 (2) Javaのアーキテクチャ概要・概観 (3) JVMのアーキテクチャ概要  (3-1) JVMの概観  (3-2) JVMの主要サブシステム1:Class …

JavaのMapの種類や特徴について(HashMap/LinkedHashMap/TreeMap)

<目次> (1) JavaのMapの種類や特徴について(HashMap/LinkedHashMap/TreeMap)  (1-1) Mapとは?  (1-2) Mapの種類や特徴   (1-2-1) …

TwitterAPIのJavaでの使い方をご紹介~【入門編】Twitter4j導入~ハッシュタグでツイート検索するまで~

<目次> (1) TwitterAPIのJavaでの使い方をご紹介  (1-1) STEP0:前提条件  (1-2) STEP1:ライブラリ(jar)のダウンロード  (1-3) STEP2:アプリケ …

JavaScriptでAttributeの値を削除(Remove)する方法

<目次> (1) JavaScriptでAttributeの値を削除(Remove)する方法  (1-1) 構文  (1-2) サンプルプログラム   (1-2-1) サンプルプログラムの概要   ( …

Javaで正規表現を使ってURLを文字列から検出する方法

<目次> (1) Javaで正規表現を使ってURLを文字列から検出する方法  (1-1) 構文  (1-2) 構文の説明  (1-3) サンプルプログラム  (1-4) ツールのご紹介 (1) Jav …

  • English (United States)
  • 日本語
Top