Rainbow Planet (GT×IT×SP×SA)

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

01_IT技術 (Technology) 03_Java

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

投稿日:

(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/Tatsuya-Yazaki";		
		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審査用広告コード


-01_IT技術 (Technology), 03_Java

執筆者:


comment

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

関連記事

Linux – シェルスクリプト入門(Hello World/引数・変数/条件分岐/繰り返し処理)

シェルスクリプトの作成方法について ■目次 (1)シェルスクリプトでHello World (2)シェルスクリプトで変数/引数を使う (3)シェルスクリプトで条件分岐を記述 (4)シェルスクリプトで繰 …

Microsoft Azureとは?概要や特徴および利用方法についての解説

(0)目次&概説 (1) Azureとは?  (1-1) IaaSとは?  (1-2) PaaSとは?  (1-3) IDaaSとは? (2) Azureのデータセンター  (2-1) Azureのデ …

Javaのstatic変数とは?その特徴及び付けた場合と付けない場合の違いを解説

(0)目次&概説 (1) static修飾子  (1-1) staticメンバとは?  (1-2) static変数   (1-2-1) static変数の説明と特徴   (1-2-2) static …

Linuxサーバ(CentOS6)にOracleDB11gをインストールする(その4)

掲題の通り、LinuxにOracleDB(11g)をインストールする方法について書きます。 「(その3)」の続編記事です。 http://rainbow-engine.com/2017/05/05/l …

Linuxサーバ(CentOS6)にEclipse(OXYGEN)をインストールする

0.目次 (1) JDKの概要  (1-1) JDKの種類  (1-2) JDKのバージョン(2018年2月時点) (2) JDKのインストール  (2-1) wget コマンドでJDK の rpm …

  • English (United States)
  • 日本語
Top