Javaでニコニコ動画検索APIをたたくExample [JSON, JSONObject, JSONIC, Guava]

題目の通りです。
Twitterアプリは作ったことがあるのですが、ラッパークラスを何も使わず
HttpURLConnectionを自分で立ててやったことは無かったのと、おもにJSONの扱いでだいぶハマったので反省程度に通ったやり方を載せておきます。

基本はここ
How to stream a JSON object to a HttpURLConnection POST request - Stack Overflow
http://stackoverflow.com/questions/21974407/how-to-stream-a-json-object-to-a-httpurlconnection-post-request

```java

import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.net.HttpURLConnection;
import java.net.URL;
import java.util.List;

import org.json.JSONObject;

import com.google.common.collect.ImmutableMap;
import com.google.common.collect.Lists;

import net.arnx.jsonic.JSON;


public class NiconicoCrawler {

    public final static void main(String[] args) throws Exception {
    	
    	URL url = new URL("ニコニコ動画スナップショット検索API エンドポイントURL");
    	
    	/*
    	 * クラス NicoQuery
    	 * +query:String 検索ワード
    	 * +service:List<String> video一択
    	 * +search:List<String> キーワードかタグか
    	 * +join:List<String> 返り値を0以上指定
    	 * +filters:List<Map<String, String>> フィルター
    	 * +sort_by:String どの要素で順序づけするか
    	 * +issuer:String アプリの名前
    	 */
    	NicoQuery nicoQuery = new NicoQuery();
    	nicoQuery.query = "ミクオリジナル曲";
    	nicoQuery.service = (List<String>) Lists.newArrayList("video");
    	nicoQuery.search = (List<String>) Lists.newArrayList("tags_exact");
    	nicoQuery.join = (List<String>) Lists.newArrayList("cmsid", "title", "start_time");
    	nicoQuery.filters = Lists.newArrayList(ImmutableMap.of(
    		"type", "range",
    		"field", "start_time",
    		"from", "2014-12-01 00:00:00",
    		"to", "2014-12-20 00:00:00"
    		));
    	nicoQuery.sort_by = "start_time";
    	nicoQuery.issuer = "アプリ名";

    	HttpURLConnection httpCon = (HttpURLConnection) url.openConnection();
    	httpCon.setDoOutput(true);
    	httpCon.setDoInput(true);
    	httpCon.setUseCaches(false);
    	httpCon.setRequestProperty( "Content-Type", "application/json" );
    	httpCon.setRequestProperty("Accept", "application/json");
    	httpCon.setRequestMethod("POST");
    	httpCon.connect();
    	OutputStream os = httpCon.getOutputStream();
    	OutputStreamWriter osw = new OutputStreamWriter(os, "UTF-8");
    	
    	// 送信予定のJSONをコンソールでプレビューする場合次のコメントをはずす
    	// System.out.println(JSON.encode(nicoQuery));
    	
    	osw.write(JSON.encode(nicoQuery));
    	osw.flush();
    	osw.close();
    	os.close();
    	
    	// データ受信部
    	BufferedReader br = new BufferedReader(
    		new InputStreamReader(httpCon.getInputStream(),"UTF-8"));
    	String line = null;
    	StringBuilder sb = new StringBuilder();
    	while ((line = br.readLine()) != null) {
    		sb.append(line + "\n");
    	}
    	br.close();
    	JSONObject res = new JSONObject(sb.toString());
    	System.out.println(res.toString(4));
    	
    }

}
```

・JSONの扱い方（送信時）
[JSONIC](http://jsonic.sourceforge.jp)を使いました。
まず送りたいJSONに沿った要素をフィールドに持つクラスを作ります。今回は調べてきた風に合わせましたがカプセル化した方が良いのかも。たとえば要素がリストのようになっている場合は```List<型>```、マップのようになっている場合は```List<Map<型, 型>>```というふうに作ればOKです。

そしてmain側でインスタンスを作るのですが、リストやマップの代入を楽にするために[Guava](https://code.google.com/p/guava-libraries/)(旧称 Google-collections)を使いました。
Javaでコレクションを扱うときの煩わしさを解消してくれる感じのイイやつです。
リストを宣言するときは```Lists.newArrayList()```、マップを宣言するときは```ImmutableMap.of()```です。

ここまでできたらこのインスタンスをJSONICのencodeメソッドでOutputStreamWriterに渡してあげれば終わりです。

・JSONの扱い方（受信時）
さっき使った```BufferedReader```を使いまわしてるんですが、これは良いんでしょうか・・・知識が至らずすみません。どなたかよければ助言お願いします。
それはそれとして、基本は```BufferedReader```に```httpCon.getInputStream```を挿して```br.readLine()```してあげればOKです。
出来上がったStringは```org.json.JSONObject```でJSONになおしてみました。ここで```toString(int indentFactor)```の引数を```4```にしておくと、イイ感じに整形されて表示されますので是非やってみてください。

以上です。