java

 

google-http-java-clientで簡単httpリクエスト!

google-http-java-clientを使ったサンプルコードです。HttpClient4よりも簡単なコードでhttpリクエストする事ができます。更に、レスポンスxml・jsonをパースしてオブジェクトに変換する事もできます。

新サイト、tree-mapsを公開しました!!

tree-maps: 地図のWEB TOOLの事ならtree-mapsにお任せ!

地図に関するWEB TOOL専門サイトです!!

大画面で大量の緯度経度を一気にプロット、ジオコーディング、DMS<->DEGの相互変換等ができます!

◯ 広告

HttpClient4は便利ですが、色々冗長な部分があります。

実はHttpClient4をラップして使いやすくしたライブラリをgoogleが提供しています。

今回はこれを使ってhttpリクエストと、レスポンスのマッピングを行ってみましょう!

google-http-java-client

圧縮ファイル内のlibsフォルダ内の以下をビルドパスに通しましょう。

  • google-http-client-1.17.0-rc.jar
  • google-http-client-xml-1.17.0-rc.jar
  • httpclient-4.0.1.jar
  • httpcore-4.0.1.jar
  • commons-logging-1.1.1.jar
  • xpp3-1.1.4c.jar(xmlのパース)
  • google-http-client-jackson2-1.17.0-rc.jar(jsonのパース)
  • jackson-core-2.1.3.jar(jsonのパース)

あと、このサンプルでgoogle guavaを使っているので、guavaもビルドパスに通して下さい。

guava-libraries

import httpclient.XmlParseTest.XmlObject.Station;

import java.io.IOException;
import java.util.List;

import com.google.api.client.http.GenericUrl;
import com.google.api.client.http.HttpRequest;
import com.google.api.client.http.HttpRequestFactory;
import com.google.api.client.http.HttpRequestInitializer;
import com.google.api.client.http.HttpResponse;
import com.google.api.client.http.apache.ApacheHttpTransport;
import com.google.api.client.util.Joiner;
import com.google.api.client.util.Key;
import com.google.api.client.xml.XmlNamespaceDictionary;
import com.google.api.client.xml.XmlObjectParser;
import com.google.common.collect.Lists;

public class XmlParseTest {
    public static void main(String[] args) {
        new XmlParseTest().test();
    }

    private void test() {
        final XmlNamespaceDictionary namespace = new XmlNamespaceDictionary();
        namespace.set("urn", "heartrails:express");

        ApacheHttpTransport transport = new ApacheHttpTransport();
        HttpRequestFactory factory = transport
                .createRequestFactory(new HttpRequestInitializer() {
                    public void initialize(HttpRequest request) throws IOException {
                        request.setConnectTimeout(0);
                        request.setReadTimeout(0);
                        request.setParser(new XmlObjectParser(namespace));
                    }
                });

        try {
            String url = "https://express.heartrails.com/api/xml?method=getStations&line=JR%E5%B1%B1%E6%89%8B%E7%B7%9A";
            HttpRequest request = factory.buildGetRequest(new GenericUrl(url));
            HttpResponse response = request.execute();
            XmlObject xml = response.parseAs(XmlObject.class);
            List<Station> stations = xml.stations;
            for (Station s : stations) {
                List<String> list = Lists.newArrayList(s.x, s.y, s.prev,
                        s.next, s.line, s.postal, s.name, s.prefecture);
                System.out.println(Joiner.on(',').join(list));
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    public static class XmlObject {
        @Key("station")
        public List<Station> stations;

        public static class Station {
            @Key public String x;
            @Key public String y;
            @Key public String prev;
            @Key public String next;
            @Key public String line;
            @Key public String postal;
            @Key public String name;
            @Key public String prefecture;
        }
    }
}

このサンプルはHeartRails ExpressのAPIを使っています。

HttpClient4と違い、httpsであってもhttpと同様のコードで実行可能です。

HeartRails ExpressのAPIのレスポンスは以下のようになっています。

<response xmlns="urn:heartrails:express">
    <station>
        <x>139.738535</x>
        <next>大崎</next>
        <prev>田町</prev>
        <y>35.628135</y>
        <line>JR山手線</line>
        <postal>1080075</postal>
        <name>品川</name>
        <prefecture>東京都</prefecture>
    </station>
    <station>
        <x>139.728246</x>
        <next>五反田</next>
        <prev>品川</prev>
        <y>35.61994</y>
        <line>JR山手線</line>
        <postal>1410032</postal>
        <name>大崎</name>
        <prefecture>東京都</prefecture>
    </station>
・・・中略・・・
    <station>
        <x>139.747602</x>
        <next>品川</next>
        <prev>浜松町</prev>
        <y>35.645737</y>
        <line>JR山手線</line>
        <postal>1080023</postal>
        <name>田町</name>
        <prefecture>東京都</prefecture>
    </station>
</response>

httpリクエストのレスポンスが上記xmlで、それをオブジェクトにマッピングしています。

XmlParseTestの実行結果は以下のようになります。

139.738535,35.628135,田町,大崎,JR山手線,1080075,品川,東京都
139.728246,35.61994,品川,五反田,JR山手線,1410032,大崎,東京都
139.723909,35.625805,大崎,目黒,JR山手線,1410022,五反田,東京都
139.715729,35.633407,五反田,恵比寿,JR山手線,1410021,目黒,東京都
139.710123,35.646684,目黒,渋谷,JR山手線,1500013,恵比寿,東京都
139.701722,35.658081,恵比寿,原宿,JR山手線,1500002,渋谷,東京都
139.702715,35.671319,渋谷,代々木,JR山手線,1500001,原宿,東京都
139.702208,35.683794,原宿,新宿,JR山手線,1510051,代々木,東京都
139.700643,35.689873,代々木,新大久保,JR山手線,1600022,新宿,東京都
139.700254,35.700929,新宿,高田馬場,JR山手線,1690073,新大久保,東京都
139.703967,35.71331,新大久保,目白,JR山手線,1690075,高田馬場,東京都
139.706281,35.720393,高田馬場,池袋,JR山手線,1710031,目白,東京都
139.711085,35.730275,目白,大塚,JR山手線,1710021,池袋,東京都
139.72794,35.731786,池袋,巣鴨,JR山手線,1700005,大塚,東京都
139.740353,35.733722,大塚,駒込,JR山手線,1700002,巣鴨,東京都
139.748403,35.737025,巣鴨,田端,JR山手線,1700003,駒込,東京都
139.761575,35.737474,駒込,西日暮里,JR山手線,1140013,田端,東京都
139.766713,35.732174,田端,日暮里,JR山手線,1160013,西日暮里,東京都
139.770877,35.72739,西日暮里,鶯谷,JR山手線,1100001,日暮里,東京都
139.778032,35.721453,日暮里,上野,JR山手線,1100003,鶯谷,東京都
139.776714,35.713701,鶯谷,御徒町,JR山手線,1100005,上野,東京都
139.774717,35.707195,上野,秋葉原,JR山手線,1100005,御徒町,東京都
139.773144,35.698305,御徒町,神田,JR山手線,1010028,秋葉原,東京都
139.770879,35.69177,秋葉原,東京,JR山手線,1010044,神田,東京都
139.766709,35.681247,神田,有楽町,JR山手線,1000005,東京,東京都
139.763261,35.675037,東京,新橋,JR山手線,1000006,有楽町,東京都
139.758462,35.666298,有楽町,浜松町,JR山手線,1050004,新橋,東京都
139.757126,35.655408,新橋,田町,JR山手線,1050022,浜松町,東京都
139.747602,35.645737,浜松町,品川,JR山手線,1080023,田町,東京都

内部的にXml Pull Parser 3rd Editionを使っているため、XMLのマッピングも高速です。

import httpclient.JsonParseTest.JsonObject.PinpointLocations;

import java.io.IOException;
import java.util.List;

import com.google.api.client.http.GenericUrl;
import com.google.api.client.http.HttpRequest;
import com.google.api.client.http.HttpRequestFactory;
import com.google.api.client.http.HttpRequestInitializer;
import com.google.api.client.http.HttpResponse;
import com.google.api.client.http.apache.ApacheHttpTransport;
import com.google.api.client.json.jackson2.JacksonFactory;
import com.google.api.client.util.Joiner;
import com.google.api.client.util.Key;
import com.google.api.client.xml.XmlNamespaceDictionary;
import com.google.common.collect.Lists;

public class JsonParseTest {
    public static void main(String[] args) {
        new JsonParseTest().test();
    }

    private void test() {
        final XmlNamespaceDictionary namespace = new XmlNamespaceDictionary();
        namespace.set("", "");

        ApacheHttpTransport transport = new ApacheHttpTransport();
        HttpRequestFactory factory = transport
                .createRequestFactory(new HttpRequestInitializer() {
                    public void initialize(HttpRequest request) throws IOException {
                        request.setConnectTimeout(0);
                        request.setReadTimeout(0);
                        request.setParser(new JacksonFactory().createJsonObjectParser());
                    }
                });

        try {
            String url = "http://weather.livedoor.com/forecast/webservice/json/v1?city=400040";
            HttpRequest request = factory.buildGetRequest(new GenericUrl(url));
            HttpResponse response = request.execute();
            JsonObject json = response.parseAs(JsonObject.class);
            List<PinpointLocations> stations = json.pinpointLocations;
            for (PinpointLocations s : stations) {
                List<String> list = Lists.newArrayList(s.link, s.name);
                System.out.println(Joiner.on(',').join(list));
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    public static class JsonObject {
        @Key("pinpointLocations")
        public List<PinpointLocations> pinpointLocations;

        public static class PinpointLocations {
            @Key public String link;
            @Key public String name;
        }
    }
}

このサンプルはlivedoor お天気WebサービスのAPIを使っています。

レスポンスは先ほどと違い、jsonになっています。

livedoor お天気WebサービスのAPIのレスポンスは以下のようになっています。

大きめのjsonのため、一部抜粋としています。

{
    "pinpointLocations": [
        {
            "link": "http://weather.livedoor.com/area/forecast/4020200", 
            "name": "大牟田市"
        }, 
        {
            "link": "http://weather.livedoor.com/area/forecast/4020300", 
            "name": "久留米市"
        }, 
 ・・・中略・・・
        {
            "link": "http://weather.livedoor.com/area/forecast/4054400", 
            "name": "広川町"
        }
    ], 
}

httpリクエストのレスポンスが上記jsonで、それをオブジェクトにマッピングしています。

JsonParseTestの実行結果は以下のようになります。

http://weather.livedoor.com/area/forecast/4020200,大牟田市
http://weather.livedoor.com/area/forecast/4020300,久留米市
http://weather.livedoor.com/area/forecast/4020700,柳川市
http://weather.livedoor.com/area/forecast/4021000,八女市
http://weather.livedoor.com/area/forecast/4021100,筑後市
http://weather.livedoor.com/area/forecast/4021200,大川市
http://weather.livedoor.com/area/forecast/4021600,小郡市
http://weather.livedoor.com/area/forecast/4022500,うきは市
http://weather.livedoor.com/area/forecast/4022800,朝倉市
http://weather.livedoor.com/area/forecast/4022900,みやま市
http://weather.livedoor.com/area/forecast/4044700,筑前町
http://weather.livedoor.com/area/forecast/4044800,東峰村
http://weather.livedoor.com/area/forecast/4050300,大刀洗町
http://weather.livedoor.com/area/forecast/4052200,大木町
http://weather.livedoor.com/area/forecast/4054400,広川町

内部的にJacksonを使っているため、jsonのマッピングも高速です。

◯ 広告