SQLの窓

2017年05月25日


Java で JSON 文字列を オブジェクトに変換する Google Gson の基本 4 パターン

ほぼ Google Gson のユーザガイドに記述されている内容です。
一般 JSON オブジェクトフォーマット

JSON 文字列のルートがいきなり、 JSON オブジェクトの一般プロパティになっている場合です。
{
    "link": "http://www.yahoo.co.jp/",
    "name": "Yahoo! JAPAN"
}
一番使う事の多いパターンの基本で、そのフォーマットのクラス定義を作成して、Gson に展開してもらいます。 一般 配列フォーマット JSON 文字列のルートがいきなり、 JSON オブジェクトの配列になっている場合で、データとしては特殊な部類になります。
[
    "http://www.yahoo.co.jp/",
    "Yahoo! JAPAN"
]
ですが、Gson 側では以下のように比較的簡単に扱えます String[] data = gson.fromJson(json, String[].class); また、これは Java での作業の都合で、ArrayList に変更する事も可能です。(但し、少し面倒です) Type arrayListType = new TypeToken<ArrayList<String>>(){}.getType(); ArrayList<String> al = gson.fromJson(json, arrayListType); 配列の中のデータ毎に型が違うフォーマット
[
    "サイトデータ",
    1,
    {
        "link": "http://www.yahoo.co.jp/",
        "name": "Yahoo! JAPAN"
    }
]
このタイプが一番面倒です。通常使われる事は無いと思いますが、使用する場合は一つ一つ対応する事になると思います。( Gson でのオリジルサンプルコードはここにあります ) オブジェクト内にオブジェクト配列
{
    "title": "サイトデータ",
    "number": 2,
    "urlList": [
        {
            "link": "http://www.yahoo.co.jp/",
            "name": "Yahoo! JAPAN"
        },
        {
            "link": "https://www.google.co.jp/",
            "name": "Google"
        }
    ]
}
データフォーマットとしてはこれが一番優れており、全てクラスを定義する事によって容易に対応できます。
import java.lang.reflect.Type;
import java.util.ArrayList;

import com.google.gson.Gson;
import com.google.gson.JsonArray;
import com.google.gson.JsonParser;
import com.google.gson.reflect.TypeToken;


public class Main {

	// メンバ用クラス
	class LinkFormat {
		String link;
		String name;
	}
	
	// メンバに配列
	class SiteData {
		String title;
		int number;
		
		LinkFormat[] urlList;
	}
	
	// メンバに ArrayList
	class SiteDataList {
		String title;
		int number;
		
		ArrayList <LinkFormat> urlList;
	}
		
	public static void main(String[] args) {
	
		String json = null;
		
		// 一般 JSON オブジェクトフォーマット
		System.out.println("-----------------------------------------");
		
		json = "";
		json += "{";
		json += 	"\"link\":\"http://www.yahoo.co.jp/\",";
		json += 	"\"name\":\"Yahoo! JAPAN\"";
		json += "}";
		System.out.println(json);

		Gson gson = new Gson();

		// オブジェクトに変換
		System.out.println("-----------------------------------------");
		
		LinkFormat linkFormat = gson.fromJson(json, LinkFormat.class);

		System.out.println(linkFormat.link);
		System.out.println(linkFormat.name);

		// 一般 配列フォーマット
		System.out.println("-----------------------------------------");
		
		json = "";
		json += "[";
		json += 	"\"http://www.yahoo.co.jp/\",";
		json += 	"\"Yahoo! JAPAN\"";
		json += "]";
		System.out.println(json);

		// 配列に変換
		String[]  data = gson.fromJson(json, String[].class);

		System.out.println(data[0]);
		System.out.println(data[1]);

		// ArrayListに変換
		System.out.println("-----------------------------------------");
		
		Type arrayListType = new TypeToken<ArrayList<String>>(){}.getType();
		ArrayList<String>  al = gson.fromJson(json, arrayListType);

		System.out.println(al.get(0));
		System.out.println(al.get(1));

		// 特殊 JSON オブジェクト配列フォーマット
		System.out.println("-----------------------------------------");
		
		json = "";
		json += "[";
		json += 	"\"サイトデータ\",";
		json += 	"1,";
		json += 	"{";
		json += 		"\"link\":\"http://www.yahoo.co.jp/\",";
		json += 		"\"name\":\"Yahoo! JAPAN\"";
		json += 	"}";
		json += "]";
		System.out.println(json);

		// JSON 文字列配列内の型が違う場合はひとつひとつ対応
		JsonParser parser = new JsonParser();
		JsonArray array = parser.parse(json).getAsJsonArray();
		String title = gson.fromJson(array.get(0), String.class);
		int number = gson.fromJson(array.get(1), int.class);
		LinkFormat lf = gson.fromJson(array.get(2), LinkFormat.class);

		System.out.println( title );
		System.out.println( number );
		System.out.println( lf.link );
		System.out.println( lf.name );

		// JSON オブジェクト内にオブジェクト配列
		System.out.println("-----------------------------------------");
		
		json = "";
		json += "{";
		json += "\"title\" : \"サイトデータ\",";
		json += "\"number\" : 2,";
		json += "\"urlList\" : [";
		json += 	"{";
		json += 		"\"link\":\"http://www.yahoo.co.jp/\",";
		json += 		"\"name\":\"Yahoo! JAPAN\"";
		json += 	"},";
		json += 	"{";
		json += 		"\"link\":\"https://www.google.co.jp/\",";
		json += 		"\"name\":\"Google\"";
		json += 	"}";
		json += "]";
		json += "}";
		System.out.println(json);
		
		// 配列バージョン
		SiteData sd = gson.fromJson(json, SiteData.class);
		System.out.println( sd.title );
		System.out.println( sd.number );
		System.out.println( sd.urlList[0].link );
		System.out.println( sd.urlList[0].name );
		System.out.println( sd.urlList[1].link );
		System.out.println( sd.urlList[1].name );

		// ArrayList バージョン
		SiteDataList sdl = gson.fromJson(json, SiteDataList.class);
		System.out.println( sdl.title );
		System.out.println( sdl.number );
		System.out.println( sdl.urlList.get(0).link );
		System.out.println( sdl.urlList.get(0).name );
		System.out.println( sdl.urlList.get(1).link );
		System.out.println( sdl.urlList.get(1).name );

	}

}


※ 整形したい場合は以下のようにします
// オブジェクトを整形して JSON 文字列に変換する
Gson gsonPretty = new GsonBuilder().setPrettyPrinting().create();
String jsonString = gsonPretty.toJson(sd);


タグ:java JSON
posted by lightbox at 2017-05-25 21:41 | Java | このブログの読者になる | 更新情報をチェックする

2016年05月31日


Java のコンソールで NAVER の RSS を取得して、title 部分を正規表現で加工して表示するサンプル

java.util.regex.Matcher
java.util.regex.Pattern

groupCount で取得されるのは、部分一致した数なので、() を使用しなければ、戻り値は 0 となります。また、その場合は group() で取得できますし。group(0) でも取得できます。

なので、常に pattern に一致する文字列は group(0) です。group(n) で n が 1 以上は部分一致となります。
よって、部分一致のみのループは、for( int i = 1; i <= m.groupCount(); i++ ) となります。
import java.io.BufferedReader;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.URL;
import java.util.regex.Matcher;
import java.util.regex.Pattern;


public class Main {

	public static void main(String[] args) {
		
		Pattern p;
		Matcher m;
		int len;

		print("処理開始");

		// NAVER の RSS
		String str = httpGet("http://matome.naver.jp/feed/hot");

        // 部分一致の無い パターンを生成
        p = Pattern.compile("<title>.+?</title>");
        m = p.matcher(str);

        // 部分一致した数( 0 になります )
        len = m.groupCount();
        print( Integer.toString(len) );

        while(m.find()) {
        	// 部分一致は無いので、m.group() で パターン
        	// に対する全体一致を取得
       		System.out.println(m.group());
        }

		print("------------------------------------------");
        
        // 部分一致のあるパターンを生成
        p = Pattern.compile("<title>(.+?)</title>");
        m = p.matcher(str);

        // 部分一致した数 ( 1になります )
        len = m.groupCount();
        print( Integer.toString(len) );
        
        while(m.find()) {
        	// m.group(0) はパターンに対する全体一致なので
        	// 1 から始めて部分一致のみ表示
        	for( int i = 1; i < (len +1); i++) {
        		System.out.println(m.group(i));
        	}
        }
        
		print("------------------------------------------");
        
        // 部分一致のあるパターンを生成
        p = Pattern.compile("(<title>)(.+?)(</title>)");
        m = p.matcher(str);

        len = m.groupCount();
        print( Integer.toString(len) );

        String partsString;
        StringBuilder buffer;
        while(m.find()) {
    		buffer = new StringBuilder();
        	for( int i = 1; i < (len +1); i++) {

        		// title 開始タグ
        		if ( i == 1) {
        			buffer.append("『");
        		}
        		// title 内容
        		if ( i == 2) {
            		partsString = m.group(2);
            		// String クラスの正規表現置換
            		// 文の区切り的文字で改行
            		partsString = partsString.replaceAll("[。、.…!?]+", "\n");
        			buffer.append(partsString);
        		}
        		// title 終了タグ
        		if ( i == 3) {
        			buffer.append("』");
        		}
        	}
    		print(buffer.toString());
    		print("");
        }

	}
	
	// ********************************
	// データ表示用
	// ********************************
	public static void print( String s ) {
		System.out.println(s);
	}	

	// ********************************
	// static void main より呼び出す為の
	// static な インターネットアクセス関数 
	// ********************************
	public static String httpGet( String s ) {

		String result = "";

		try {
			URL url = new URL(s);

			HttpURLConnection http = (HttpURLConnection)url.openConnection();
			http.setRequestMethod("GET");
			http.connect();
			InputStream is = http.getInputStream();

			InputStreamReader isr = new InputStreamReader(is,"UTF8");
			BufferedReader br = new BufferedReader(isr);
			String line_buffer;
			StringBuilder sb = new StringBuilder();

			while(null != (line_buffer = br.readLine() )) {

				sb.append(String.format("%s\n",line_buffer));

			}

			br.close();
			isr.close();
			is.close();

			result = sb.toString();

		} catch (Exception e) {
			e.printStackTrace();
		}

		return result;

	}	

}




posted by lightbox at 2016-05-31 12:00 | Java | このブログの読者になる | 更新情報をチェックする

2015年06月28日


Eclipse で、文字列内のファイルのパスの \ 記号を \\ にする方法


 

このチェックボックスをオンにすると、"" の中にクリップボードから文字列を貼り付ける場合に、" や \ の後になんらかの文字が続いている場合は、" が \" に \ が \\ になります。

この為、Windows のパスをそのまま "" の中に貼り付けると、全ての \ が \\ となり、そのまま使用可能になります。

※ " や \ を単独で貼り付けても変化はしません。
※ コメント内は対象になりません

既に \ で作成されている文字列は、範囲を選択して SHIFT + DEL で削除して、再度貼り付けるといいです。

※ この場合、SHIFT + INS で貼り付けるとキー操作は最速になります。


posted by lightbox at 2015-06-28 21:43 | Java | このブログの読者になる | 更新情報をチェックする

2015年05月05日


Java : Google gson 2.3.1 で JSON 文字列を定義済みのクラスを使ってオブジェクト化

処理としては、以下の記事の続きになります。

Eclipse + JFace : HttpURLConnection で GET

※ Google gson のダウンロードはこちら
※ Google gson の実装はこちら
※ オンラインドキュメントはこちら

まずは、JSON データとして WEB API を

Livedoor の お天気Webサービスを使用します。地域id を指定するだけで、その地域の天気データを取得できる API です。

▼ 大阪
http://weather.livedoor.com/forecast/webservice/json/v1?city=270000

JSON のチェックと整形は JSONLint サービスでどうぞ


Google gson 用のクラス定義

JSON のフォーマットに合わせて定義しますが、順序を合わす必要は無く、名前(変数名)を一致させるようにします。サンプルでは、文字列と整数を使っていますが、JsonElement で可能な変換はできると思います。

Getter と Setter でアプリケーションに必要な変換をそこで定義してしまってもいいと思います。

public class Weather {

	class PinpointLocation {
		String link;
		String name;
	}

	class Text {
		String text;
		String publicTime;
	}

	class Location {
		String city;
		String area;
		String prefecture;
	}

	class IntTest {
		ImageSize image;
	}

	class ImageSize {
		int width;
		int height;
	}

	PinpointLocation[] pinpointLocations;
	Location location;
	IntTest copyright;
	Text description;

	// Getter と Setter で処理する
	private String publicTime;

	String getPublicTime() {
		return publicTime.substring(0, 10);
	}
	void setPublicTime(String publicTime) {
		this.publicTime = publicTime;
	}

}


実行
	/**
	 * Create contents of the application window.
	 * @param parent
	 */
	@Override
	protected Control createContents(Composite parent) {
		Composite container = new Composite(parent, SWT.NONE);
		container.setLayout(null);
		{
			Button btnNewButton = new Button(container, SWT.NONE);
			btnNewButton.addSelectionListener(new SelectionAdapter() {
				@Override
				public void widgetSelected(SelectionEvent e) {
					System.out.println("ボタンの処理");
					HttpGet hg = new HttpGet();
					String result =
						hg.execute(
							"http://weather.livedoor.com/forecast/webservice/json/v1?city=270000",
							"utf-8"
							);
					System.out.println(result);

					Gson gson = new Gson();
					Weather json = gson.fromJson(result,Weather.class);

					// 内部クラスの変数として定義されたものをそのまま利用
					System.out.println(json.location.city);
					System.out.println(json.location.area);
					System.out.println(json.location.prefecture);
					System.out.println(json.description.text);
					System.out.println(json.description.publicTime);

					// Setter でセットされたものを Getter で取得
					System.out.println(json.getPublicTime());

					// クラスの配列として定義していたものを使用
					for( int i = 0; i < json.pinpointLocations.length; i++ ) {
						System.out.println(json.pinpointLocations[i].link);
						System.out.println(json.pinpointLocations[i].name);
					}

					// 数値変数
					System.out.println(json.copyright.image.width);
					System.out.println(json.copyright.image.height);

				}
			});
			btnNewButton.setBounds(10, 10, 81, 28);
			btnNewButton.setText("New Button");
		}

		return container;
	}



タグ:java JSON
posted by lightbox at 2015-05-05 07:15 | Java | このブログの読者になる | 更新情報をチェックする

2015年05月04日


Java : Google gson 2.3.1 で、JSON 文字列のフォーマットが解らなくてもなんとかなる『ベタ』な処理方法

本来は、fromJson メソッドを使って、JSON のフォーマットに合った定義済みのクラスを使ってオブジェクト化しますが、もっとリアルに JSON の文字列と格闘したい時に使う方法です。

処理としては、以下の記事の続きになります。

Eclipse + JFace : HttpURLConnection で GET

※ Google gson の実装はこちら
※ オンラインドキュメントはこちら

ソースコード
	/**
	 * Create contents of the application window.
	 * @param parent
	 */
	@Override
	protected Control createContents(Composite parent) {
		Composite container = new Composite(parent, SWT.NONE);
		container.setLayout(null);
		{
			Button btnNewButton = new Button(container, SWT.NONE);
			btnNewButton.addSelectionListener(new SelectionAdapter() {
				@Override
				public void widgetSelected(SelectionEvent e) {
					System.out.println("ボタンの処理");
					HttpGet hg = new HttpGet();
					String result =
							hg.execute(
									"http://localhost/basic/log_01/log.json",
									"utf-8"
									);
//					String result = hg.execute();
					System.out.println(result);

					// パーサーを取得
					JsonParser jp = new JsonParser();
					// 文字列をパース
					JsonElement je = jp.parse(result);
					// JsonObject を取得する
					JsonObject jo = je.getAsJsonObject();
					// ***********************************
					// 最初が、唯一の  "item" である事が解っており
					// しかもそれは配列なので、配列として取得する
					// ***********************************
					JsonArray ja = jo.getAsJsonArray("item");

					// ***********************************
					// 配列なので、一覧表示する為のイテレータ
					// を作成
					// ***********************************
					Iterator<JsonElement> it = ja.iterator();

					// ***********************************
					// JsonElement は、どのようなフォーマット
					// かは、定義者次第です。
					// ▼ dataset は一つ一つの項目用です
					// ***********************************
					JsonElement dataset = null;
					while( it.hasNext() ) {
						// 一つ取得( ここでは、JsonObject である事が解っています )
						dataset = it.next();
						// ***********************************
						// JsonObject から get でデータを取得します。
						// 取得した時点では  JsonElement ですが、
						// 文字列と解っているので変換します
						// ***********************************
						String text = dataset.getAsJsonObject().get("text").getAsString();
						System.out.println(text);

						// ***********************************
						// subject キーがある場合は取得します
						// ***********************************
						if ( dataset.getAsJsonObject().has("subject") ) {
							String subject = dataset.getAsJsonObject().get("subject").getAsString();
							System.out.println(subject);
						}
					}

				}
			});
			btnNewButton.setBounds(10, 10, 81, 28);
			btnNewButton.setText("New Button");
		}

		return container;
	}
ここでは、以下のようなフォーマットである事を前提に処理を書いていますが、JSON オブジェクトの中を次々に読んでタイプをチェックしながら処理する自己呼び出しのメソッドで全ての解析は可能です。





タグ:java JSON
posted by lightbox at 2015-05-04 22:30 | Java | このブログの読者になる | 更新情報をチェックする

Eclipse のホバーで追加したライブラリの javadoc を表示させる手順



ここで使っているのは、Google gson 2.3.1 です

そもそも、Google gson を使用する為に、プロジェクトに libs フォルダを作成します。後々、Android にも使うのでこうしています。そしてその中にダウンロードした gson-2.3.1.jar を保存しますが、今回わかりやすく同じフォルダに gson-2.3.1-javadoc.jar を保存しました。決してプロジェクトの中に javadoc を入れる必要はありませんが、テスト環境では便利なのでこうしています。

gson-2.3.1.jar の参照





プロジェクト内に置いてるので、『Jar 追加ボタン』でいいです。プロジェクト外なら『外部 Jar 追加ボタン』で。



追加すると、以下のようになるので、gson 2.3.1.jar を開いて内容を確認します。



Javadoc ロケーションが、『なし』になっているので、選択して編集ボタンをクリックします



javadoc が、PC のディレクトリ内にあるのならばその位置を上のラジオボタンで処理しますが、.jar であるならば下のラジオボタンを選択して、.jar を選択します。その後、検証ボタンで正しい情報が揃っているかチェックされるのでクリックします。.jar の中の任意の位置を指定する必要がある場合は、二つ目の参照ボタンで選択します。

以上で、カーソルをホバーすると、javadoc が表示されるはずです。



タグ:Eclipse javadoc
posted by lightbox at 2015-05-04 21:48 | Java | このブログの読者になる | 更新情報をチェックする
Seesaa の各ページの表示について
Seesaa の 記事がたまに全く表示されない場合があります。その場合は、設定> 詳細設定> ブログ設定 で 最新の情報に更新の『実行ボタン』で記事やアーカイブが最新にビルドされます。

Seesaa のページで、アーカイブとタグページは要注意です。タグページはコンテンツが全く無い状態になりますし、アーカイブページも歯抜けページはコンテンツが存在しないのにページが表示されてしまいます。

また、カテゴリページもそういう意味では完全ではありません。『カテゴリID-番号』というフォーマットで表示されるページですが、実際存在するより大きな番号でも表示されてしまいます。

※ インデックスページのみ、実際の記事数を超えたページを指定しても最後のページが表示されるようです

対処としては、このようなヘルプ的な情報を固定でページの最後に表示するようにするといいでしょう。具体的には、メインの記事コンテンツの下に『自由形式』を追加し、アーカイブとカテゴリページでのみ表示するように設定し、コンテンツを用意するといいと思います。


※ エキスパートモードで表示しています

アーカイブとカテゴリページはこのように簡単に設定できますが、タグページは HTML 設定を直接変更して、以下の『タグページでのみ表示される内容』の記述方法で設定する必要があります

<% if:page_name eq 'archive' -%>
アーカイブページでのみ表示される内容
<% /if %>

<% if:page_name eq 'category' -%>
カテゴリページでのみ表示される内容
<% /if %>

<% if:page_name eq 'tag' -%>
タグページでのみ表示される内容
<% /if %>
この記述は、以下の場所で使用します
container 終わり

フリーフォントで簡単ロゴ作成
フリーフォントでボタン素材作成
フリーフォントで吹き出し画像作成
フリーフォントではんこ画像作成
ほぼ自由に利用できるフリーフォント
フリーフォントの書体見本とサンプル
画像を大きく見る為のウインドウを開くボタンの作成

CSS ドロップシャドウの参考デモ
BUTTONS (CSS でボタン)
イラストAC
ぱくたそ
写真素材 足成
フリーフォント一覧
utf8 文字ツール
右サイド 終わり
base 終わり