TwitterのTimelineを表示する。

何となく、勉強のために、というか諸事情によりTwitterClientを作ってみようと思いました。

197Xsで紹介したTwitter4Jを使えば簡単だったのですが、これも諸事情によりそのまま使えないため、まるっと自作してみようかな、と。(レスポンス・ボディをXMLパーサに食わせる前にあれこれしないといけない場合を想定)


で、実際作ってみたのですがid:daisuke-mに高速で教えてもらった方法を参考にJDOMを使ってみようとこれまた何となく思ったのでやってみました。(getMyTimelineCase2がdaisuke-m版)

import java.io.IOException;
import java.io.InputStream;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.List;

import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.transform.TransformerException;

import org.jdom.Document;
import org.jdom.Element;
import org.jdom.JDOMException;
import org.jdom.input.SAXBuilder;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import org.w3c.dom.traversal.NodeIterator;
import org.xml.sax.SAXException;

import com.sun.org.apache.xpath.internal.XPathAPI;

public class ConnecterSample {

	public static void main(String[] args) {
		ConnecterSample sample = new ConnecterSample("itengineer");
		System.out.println(sample.getMyTimelineCase1());
		System.out.println(sample.getMyTimelineCase2());
	}

	static final String MY_TIMELINE_URL = "http://twitter.com/statuses/friends_timeline/";
	String id;
	ConnecterSample(String id) {
		this.id = id;
	}
	public String getMyTimelineCase1() {
		StringBuilder sb = new StringBuilder();
		URL url;
		HttpURLConnection conn = null;
		try {
			url = new URL(MY_TIMELINE_URL + this.id + ".xml");
			conn = (HttpURLConnection) url.openConnection();
			conn.setRequestMethod("POST");
			conn.setInstanceFollowRedirects(false);
			conn.setRequestProperty("Accept-Language", "ja;q=0.7,en;q=0.3");
			InputStream is = conn.getInputStream();

			SAXBuilder builder = new SAXBuilder();
			Document doc = builder.build(is);
			Element elem = doc.getRootElement();
			List<Element> lis = elem.getChildren("status");
			for (Element e:lis) {
				sb.append(e.getChild("user").getChildTextTrim("screen_name"));
				sb.append(":");
				sb.append(e.getChildTextTrim("text"));
				sb.append("\n");
			}
		} catch (MalformedURLException e1) {
			e1.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		} catch (JDOMException e) {
			e.printStackTrace();
		} finally {
			if (conn != null) {
				conn.disconnect();
			}
		}
		return sb.toString();
	}
	public String getMyTimelineCase2() {
		StringBuilder sb = new StringBuilder();
		URL url;
		HttpURLConnection conn = null;
		try {
			url = new URL(MY_TIMELINE_URL + this.id + ".xml");
			conn = (HttpURLConnection) url.openConnection();
			conn.setRequestMethod("POST");
			conn.setInstanceFollowRedirects(false);
			conn.setRequestProperty("Accept-Language", "ja;q=0.7,en;q=0.3");
			InputStream is = conn.getInputStream();

			DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
			factory.setNamespaceAware(true);
			DocumentBuilder builder;
			builder = factory.newDocumentBuilder();
			org.w3c.dom.Document doc = builder.parse(is);
			NodeIterator nl = XPathAPI.selectNodeIterator(doc, "//status");
			Node node;
			while ((node = nl.nextNode()) != null) {
				NodeList childNodes = node.getChildNodes();
				sb.append(childNodes.item(17).getChildNodes().item(5).getTextContent());
				sb.append(":");
				sb.append(childNodes.item(5).getTextContent());
				sb.append("\n");
			}
		} catch (MalformedURLException e1) {
			e1.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		} catch (ParserConfigurationException e) {
			e.printStackTrace();
		} catch (SAXException e) {
			e.printStackTrace();
		} catch (TransformerException e) {
			e.printStackTrace();
		} finally {
			if (conn != null) {
				conn.disconnect();
			}
		}
		return sb.toString();
	}
}

もしかしたら、DocumentBuilderでもElement名でデータを持ってこれる方法があるのかも知れませんが、そこはあまり調べてません。でも、JDOMの方がなんとなくわかりやすいコードにはなったような気がする。。。


とか悩んでいる事からして、とても初歩的な事かも知れないんですが、まぁ僕がしょぼいんでw