題目の通りです。
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
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を使いました。
まず送りたいJSONに沿った要素をフィールドに持つクラスを作ります。今回は調べてきた風に合わせましたがカプセル化した方が良いのかも。たとえば要素がリストのようになっている場合はList<型>
、マップのようになっている場合はList<Map<型, 型>>
というふうに作ればOKです。
そしてmain側でインスタンスを作るのですが、リストやマップの代入を楽にするためにGuava(旧称 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
にしておくと、イイ感じに整形されて表示されますので是非やってみてください。
以上です。