Rainbow Engine

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

Java

JavaでJSON形式のデータから値を抽出する方法+代表的なエラー対処も紹介

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

(0)目次&概説

(1) 記事の目的
 (1-1) 目的
(2) JSON形式の概要
 (2-1) JSON形式とは?
 (2-2) JSON形式のフォーマット
(3) JSON形式の抽出方法・事前準備
 (3-1) JSON形式の抽出ルール
 (3-2) JSON in Javaライブラリ追加の手順
 (3-3) JSONの抽出構文
(4) JSON抽出プログラム実装例
 (4-1) サンプルプログラム
 (4-2) 実行結果
(5) JSON配列の抽出について
(6) エラー対応
 (6-1) エラー1:java.lang.NoClassDefFoundError
 (6-2) エラー2:java.lang.ClassNotFoundException

(1) 記事の目的

(1-1) 目的

この記事の目的はJSON形式のデータをJavaで抽出するために必要な「前準備」と、実施の「サンプルコード」を紹介する事です。

目次にもどる

(2) JSON形式の概要

(2-1) JSON形式とは?

JSON形式はデータのシリアライズや、ネットワーク越しの転送に使われる形式です。シリアライズは直訳すると「複数の要素を一連にする」といったニュアンスの意味になるが、システム的には、実行中のプログラムがメモリ上で保持しているオブジェクト等を、文字列に変換したり所定のデータ形式に変換して、保存や連携が出来るようにする処理の事を言います。このJSON形式はサーバとウェブアプリ間でのデータのやり取りをする際の形式として、主にXMLの代替手段で利用されます。特にJavaScript言語との親和性が良く、人間的にも機械的にも解析がし易いといったメリットもあります。

目次にもどる

(2-2) JSON形式のフォーマット

・{ }で全体を括っています。
・「名前」と「値」をペアにしていて「名前」は「key」と呼び「値」は「value」と呼びます。
・各keyと値はダブルクォーテーション「”」で括ります。
・ペアとペアの間はカンマで区切ります。

(例)

//### 形式の例
{
  "[名前]" : "[値]"
  ,"[名前]" : "[値]"
  ,"[名前]" : "[値]"
}
//### 実際の例
{
	"address1": "東京都",
	"address2": "新宿区",
	"address3": "新小川町",
	"kana1": "トウキョウト",
	"kana2": "シンジュクク",
	"kana3": "シンオガワマチ",
	"prefcode": "13",
	"zipcode": "1620814"
}

目次にもどる

(3) JSON形式の抽出方法・事前準備

(3-1) JSON形式の抽出ルール

JSON形式のデータを扱うにはライブラリが無いと大変になります。本記事では「Json In Java」を導入してAPIコールする例を紹介します。

https://mvnrepository.com/artifact/org.json/json/20180813

目次にもどる

(3-2) JSON in Javaライブラリ追加の手順

(3-2-1) ライブラリのダウンロード

①下記URLにアクセスして、中央付近のHomePageのリンクをクリックするとGitHubeのページに遷移します。
https://mvnrepository.com/artifact/org.json/json/20180813
(図411)①

②「JSON in Java [package org.json]」と書かれた部分の上部に「Click here if you just want~」のリンクがあるので、ここをクリックするとjarファイル「json-yyymmdd.jar」のダウンロードが始まります。
https://github.com/stleary/JSON-java

(図411)②

(3-2-2) サーバへのアップロード

TeraTerm等にログインして、jarファイルをサーバにアップロードします。

(図412)


(3-2-3) プロジェクトにjarファイルを追加

JSON形式を扱うJavaプロジェクトに対して、先程サーバにアップロードしたjarファイルを追加します。
①jarファイルを追加するプロジェクトを右クリックして「BuildPath」→「Configure Build Path」と選択していきます。
(図413)①

②左ペインで「Java Build Path」が選択されている事を確認し「Library」タブにて「Add External Jars」を押下して、先程サーバにアップロードしたjarファイルを選択します。

(図413)②

(3-2-4) 追加結果の確認

正常に追加できた事の確認として「org.json.JSONObject」パッケージをインポートし、JSONObjectのインスタンスが作成できるかどうかチェックします。

(図414)Before:JSONObjectクラスのインスタンスを作ろうとするとエラーになる

↓jarファイルの追加に伴いJSONObjectのエラーが解消する
(図414)After

目次にもどる

(3-3) JSONの抽出構文

下記1行目でJSONObjectクラスのインスタンスを作り、そこから2行目のgetStringメソッドや3行目のgetIntメソッドで値を取得しています。

JSONObject json = new JSONObject(result);
System.out.println(json.getString("login"));
System.out.println(json.getInt("id"));	

目次にもどる

(4) JSON抽出プログラム実装例

(4-1) サンプルプログラム

先程の構文を実際のプログラムに当てはめてみます。ベースとなるプログラムはGitHubのAPIをコールしてユーザ情報を取得するコードを用いてJSON形式のデータを取得し、そこから各要素を上記構文で取得します。ベースプログラム(GitHubのAPIをコールする部分)については別記事で詳細に記載しています(記事:GitHubのWebAPIをコールしてユーザー情報を取得するサンプルプログラムの解説+エラー対応も2例紹介

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;
import org.json.JSONObject;

@WebServlet("/WebAPI_IT0111")
public class IT0111_ExtractJsonData extends HttpServlet {
	private static final long serialVersionUID = 1L;
    public IT0111_ExtractJsonData() {
        super();
    }

	protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		String url = "api.github.com/users/XXXXXXXX";		
		getGithubContentUsingURLConnection(request,response,url);
	}
	
	//### メソッド名称:	getGithubContentUsingURLConnection
	//### メソッド概要:	GitHubのAPI
	//### 	【引数3】String token	:WebAPIを利用するためのトークン
	//### 	【引数4】String url		:WebAPIのURL
	public static void getGithubContentUsingURLConnection(HttpServletRequest request, HttpServletResponse response, 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));
		
		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 />");
		JSONObject json = new JSONObject(result);
		response.getWriter().append("login :	"+json.getString("login"));	out.println("<br />");
		response.getWriter().append("id :	"+json.getInt("id"));	out.println("<br />");		
	}	
}

目次にもどる

(4-2) 実行結果

このサーブレットを実際にウェブブラウザから訪問すると次のように、GitHubユーザの”login”要素と”id”要素がプリントされます。
(図433)

目次にもどる

(5) JSON配列の抽出について

次のようにJSON形式が配列になって格納されているような場合は、JSONArrayという別のクラスも使って抽出する必要があります。それについては長くなるので下記の別記事にて説明いたします。

{
        "results":
        [
                {
                        "address1": "東京都",
                        "address2": "新宿区",
                        "address3": "新小川町",
                        "zipcode": "1620814"
                },
                {
                        "address1": "神奈川県",
                        "address2": "横浜市",
                        "address3": "羽沢南",
                        "zipcode": "2210866"
                }
        ],
        "status": 200
}

記事:JavaでJSON配列から値を抽出する方法+郵便番号検索APIのサンプルプログラムも紹介

(6) エラー対応

(6-1) エラー1:java.lang.NoClassDefFoundError

(6-1-1) エラー概要

サーブレットの実行時に下記のエラーが発生。

java.lang.NoClassDefFoundError: org/json/JSONObject

(図511)

目次にもどる

(6-1-2) エラー原因

NoClassDefFoundErrorはJava実行時に起きる「エラー」です。一般的には、特定のクラスがコンパイル時には存在したが、実行時に存在しなかった場合に出るエラーで、JREによってエラーが報告されます。
今回のケースは正確な特定は出来ておりませんがjsonデータの抽出に用いた「json-yyyymmdd.jar」に関する「Web Deployment Assembly」や「外部jarファイルの追加」の設定を見直す事でエラーが解消しました。

目次にもどる

(6-1-3) エラー対処

上述の通り「外部jar」と「Web Deployment Assembly」の設定を見直します。「Web Deployment Assembly」は「外部jar」の結果を反映させるため、順番としては「外部jar」が先になります。

(a) 外部jarの見直し

①プロジェクトを右クリックして「BuildPath」⇒「Configure Build Path」と選択
(図513)①

②右側のメニューで「Add External Jars」を選択
(図513)②

③追加対象のjarファイルを選択して「Apply and Close」で適用
(図513)③

(b) Web Deployment Assemblyの見直し
先ほどビルドパスに追加した設定をWeb Deployment Assemblyにも反映させます。
④同じプロパティの画面の左側で「Deployment Assembly」を選択し、右側メニューの「Add」を押して「Java Build Path Entries」を選択します。
(図513)④

⑤先ほどビルドパスに追加したjarファイルを選択して追加します。
(図513)⑤

目次にもどる

(6-1-4) Web Deployment Assemblyの補足・用語説明
「Web Deployment Assembly」の設定はWARファイルに含める資源を設定する画面です。用途としては別のプロジェクトを参照させたり、それをWARファイルに含めたりする際に必要な設定です。動的Webプロジェクトそのもののコンパイルを成功させるだけなら「Build Path」の設定を行えばOKだが、WARファイルの中には含まれないため、意図しない不完全なパッケージングになってしまう。昔の機能名は「Java EE Module Dependencies」という名前だった。

目次にもどる

(6-2) エラー2:java.lang.ClassNotFoundException

(6-2-1) エラー概要

サーブレットの実行時に下記のエラーが発生。

java.lang.ClassNotFoundException: org/json/JSONObject

(図521)※下記は例でエラーの再現例であり、実際のプログラムとは異なります。

目次にもどる

(6-1-2) エラー原因
ClassNotFoundExceptionはJava実行時に起きる「例外」です。一般的にはJava実行時に呼び出したクラスがclasspathに無かった場合に発生します。例えば、内部的にClass.forName()やloadClass()といったメソッドでクラスを呼んだ際に、アプリケーションによって例外がthrowされます。よくある例で、classpathのメンテをせずにjarファイルを利用しようとした時などに発生します。

目次にもどる

(6-1-3) エラー対処

jsonデータの抽出に用いた「json-yyyymmdd.jar」に関する「外部jarファイルの追加」の設定を見直す事でエラーが解消しました。

具体的な手順は「(6-1-3) エラー対処」の「(a) 外部jarの見直し」と同じです。

目次にもどる

Adsense審査用広告コード


Adsense審査用広告コード


-Java

執筆者:


comment

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

関連記事

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

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

TomcatでEclipseを使う際にserver.xmlを編集しても上書きされる事象の対処方法

<目次> (1) TomcatでEclipseを使う際にserver.xmlを編集しても上書きされる事象の対処方法  (1-1) 発生状況・エラーメッセージ  (1-2) 原因  (1-3) 対処法 …

double型で誤差が発生する件について+発生事例やサンプルプログラムも紹介

<目次> (1) double型では誤差が発生する事について  (1-1) double型は近似値を使用している  (1-2) double型の誤差の例 (1) double型で誤差が発生する件につい …

JSPでcssが適用されない(Resouce interpreted as Stylesheet but transferred with MIME type)事象のトラブルシューティング記録

<目次> (1) JSPでcssが適用されない(Resouce interpreted as Stylesheet but transferred with MIME type)事象のトラブルシューテ …

CentOS7にEclipseをインストールする手順

<目次> (1) CentOS7にEclipseをインストールする手順  (1-1) JDKのインストール  (1-2) Eclipse資源のダウンロード  (1-3) Eclipseのインストール …

  • English (United States)
  • 日本語
Top