.NETプログラミング研究 第73号 †
.NET Tips †
RESTを使ったWebサービスにアクセスする †
前回はSOAPを使ったWebサービスにアクセスする方法を紹介しましたが、今回はRESTによるWebサービスにアクセスする方法について説明します。
現在一般に公開されているWebサービスを調べてみると、RESTを採用いるWebサービスが多いようです。AmazonのようにSOAPとRESTの両方のインターフェイスを提供しているWebサービスでも、アクセスのほとんどがRESTであるといいます(注)。このように現状ではWebサービスのインターフェイスとしてRESTはSOAPよりも広く利用されていると言えそうですが、.NET FrameworkはSOAP重視のようで、MSDNでもRESTについてはほとんど(というより私の知る限りでは全く)触れられていません。
注:「REST vs. SOAP at Amazon」によると、85%がRESTの使用ということです。
しかし、.NET FrameworkではSOAPほど簡単な方法が用意されていないとはいうものの、RESTのWebサービスへのアクセスも難しいわけではありません。ここでは、Yahoo! JAPANのウェブ検索Webサービスを例に、その方法を具体的に解説します。
RESTを使ったWebサービスにアクセスする流れを簡単にまとめると、次のようになります。
- Webサービスサーバーに送信するデータを作成する。
- データを指定されたURIにHTTPの適当なメソッド(GET、POST、DELETE、PUT)により送信する。
- Webサービスサーバーから返されるXMLデータを受信する。
- 受信したデータを解析する。
リクエストを送信し、レスポンスを受信する2、3の部分は、.NET FrameworkのHttpWebRequestとHttpWebResponseクラスを使用すればよいでしょう。DOBON.NETでは、次のページでこれらの使い方を説明しています。
4の受信したXMLデータを解析する方法は、幾つか考えられます。しかし通常は、XmlDocumentクラスを使って解析するか、XMLスキーマ定義ツールXsd.exeにより作成されたクラスを使うかになるでしょう。ここではXsd.exeを利用する方法を紹介します(XmlDocumentクラスを使った方法も後述します)。
Yahoo!ウェブ検索Webサービスにアクセスする †
それではYahoo!ウェブ検索Webサービスにアクセスする方法を見ていきましょう。Yahoo!のWebサービスを使用するには「アプリケーションID」というものが必要ですので、もしなければ、これを登録しておきます。下記のページから登録できます。
Xsd.exe
まずはXsd.exeを使ってXMLデータを解析するのに役立つクラスを作成しておきます。Xsd.exeのパスは、Visual Studio 2005を「C:\Program Files\Microsoft Visual Studio 8」にインストールしているならば、
C:\Program Files\Microsoft Visual Studio 8\SDK\v2.0\Bin\Xsd.exe
のようになるでしょう。
Xsd.exeを使用するために、まずYahoo!ウェブ検索WebサービスのXMLスキーマをダウンロードしておきます。ファイル名は"WebSearchResponse.xsd"としておきます(拡張子は必ず「xsd」にしてください)。
そして次のようなコマンドを実行し、クラスを作成します。
xsd.exe /c /l:CS /n:Yahoo.jp.WebSearchResponse WebSearchResponse.xsd
「/c」は指定したスキーマと対応するクラスを作成することを意味します。「/c」の代わりに「/d」を使用してクラスを作成することもできますが、その場合はDataSetから派生したクラスが作成されます(「/d」を用いて作成したクラスの使用法は後述します)。
また「/l:CS」というのは、C#のコードを生成するという意味です。VB.NETであれば「/l:VB」、JScriptであれば「/l:JS」、Visual J#であれば「/l:VJS」とします。何も指定しないと、C#になります。
さらに作成されるクラスの名前空間を「Yahoo.jp.WebSearchResponse」とするために、「/n:Yahoo.jp.WebSearchResponse」を指定しています。「/n」を指定しないと、名前空間なしとなります。
上記のコマンドを実行することにより、WebSearchResponse.xsdのあるフォルダにWebSearchResponse.cs(「/l:VB」としているならばWebSearchResponse.vb)というクラスファイルが作成されます(違うフォルダに作成したいのであれば、「/o」オプションを指定しましょう)。このファイルをWebサービスを使用するプロジェクトに追加すれば、使用できるようになります。
クライアントアプリケーションの作成
これで準備は整いましたので、Webサービスを使うクライアントを作成しましょう。ここではWebアプリケーションを作成します。
さっそくですが、具体的なコードを紹介します。ここではフォームにテキストボックス(TextBox1)とボタン(Button1)を配置し、テキストボックスに入力された文字列をクエリーとして検索し、結果をLabel1に表示しています。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
| | <%@ Page Language="VB" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<script runat="server">
Protected Sub Button1_Click( _
ByVal sender As Object, ByVal e As System.EventArgs)
Dim requestUrl As String = _
"http://api.search.yahoo.co.jp/WebSearchService/V1/webSearch"
requestUrl += "?appid=xxxxxx"
requestUrl += "&query=" + Server.UrlEncode(TextBox1.Text)
Dim request As System.Net.HttpWebRequest = _
CType(System.Net.WebRequest.Create(requestUrl), _
System.Net.HttpWebRequest)
Dim response As System.Net.HttpWebResponse = Nothing
Dim res As Yahoo.jp.WebSearchResponse.ResultSet
Try
response = CType(request.GetResponse(), _
System.Net.HttpWebResponse)
Dim strm As System.IO.Stream = response.GetResponseStream()
Dim serializer As New System.Xml.Serialization.XmlSerializer( _
GetType(Yahoo.jp.WebSearchResponse.ResultSet))
res = CType(serializer.Deserialize(strm), _
Yahoo.jp.WebSearchResponse.ResultSet)
Catch ex As Exception
Label1.Text = "エラー:" + Server.HtmlEncode(ex.Message)
Return
Finally
If Not (response Is Nothing) Then
response.Close()
End If
End Try
Label1.Text = ""
If res.totalResultsReturned = "0" Then
Label1.Text += "該当するページが見つかりませんでした。"
Else
Label1.Text += "<b>" + _
Server.HtmlEncode(TextBox1.Text) + _
"</b> の検索結果 約 " + _
res.totalResultsAvailable + "件中 " + _
res.firstResultPosition + " - " + _
res.totalResultsReturned + " 件目<br />" + vbLf
Label1.Text += "<ul>" + vbLf
Dim item As Yahoo.jp.WebSearchResponse.ResultType
For Each item In res.Result
Label1.Text += "<li><a href=""" + _
item.ClickUrl + """>" + item.Title + "</a>"
Next item
Label1.Text += "</ul>" + vbLf
End If
End Sub
</script>
<html xmlns="http://www.w3.org/1999/xhtml" >
<head id="Head1" runat="server">
<title>Yahoo!ウェブ検索Webサービスのサンプル</title>
</head>
<body>
<form id="form1" runat="server">
<div>
<asp:TextBox ID="TextBox1" runat="server"></asp:TextBox>
<asp:Button ID="Button1" runat="server"
OnClick="Button1_Click" Text="検索" /><br />
<br />
<asp:Label ID="Label1" runat="server"
EnableViewState="False"></asp:Label>
</div>
</form>
<!-- Begin Yahoo! JAPAN Web Services Attribution Snippet -->
<span style="margin:15px 15px 15px 15px">
<a href="http://developer.yahoo.co.jp/about">Webサービス by Yahoo! JAPAN</a>
</span>
<!-- End Yahoo! JAPAN Web Services Attribution Snippet -->
</body>
</html>
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
| | <%@ Page Language="C#" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<script runat="server">
protected void Button1_Click(object sender, EventArgs e)
{
string requestUrl =
"http://api.search.yahoo.co.jp/WebSearchService/V1/webSearch";
requestUrl += "?appid=xxxxxx";
requestUrl += "&query=" + Server.UrlEncode(TextBox1.Text);
System.Net.HttpWebRequest request =
(System.Net.HttpWebRequest)System.Net.WebRequest.Create(
requestUrl);
System.Net.HttpWebResponse response = null;
Yahoo.jp.WebSearchResponse.ResultSet res;
try
{
response = (System.Net.HttpWebResponse)request.GetResponse();
System.IO.Stream strm = response.GetResponseStream();
System.Xml.Serialization.XmlSerializer serializer =
new System.Xml.Serialization.XmlSerializer(
typeof(Yahoo.jp.WebSearchResponse.ResultSet));
res = (Yahoo.jp.WebSearchResponse.ResultSet)
serializer.Deserialize(strm);
}
catch (Exception ex)
{
Label1.Text = "エラー:" + Server.HtmlEncode(ex.Message);
return;
}
finally
{
if (response != null)
response.Close();
}
Label1.Text = "";
if (res.totalResultsReturned == "0")
{
Label1.Text += "該当するページが見つかりませんでした。";
}
else
{
Label1.Text += "<b>" + Server.HtmlEncode(TextBox1.Text) +
"</b> の検索結果 約 " +
res.totalResultsAvailable + "件中 " +
res.firstResultPosition + " - " +
res.totalResultsReturned + " 件目<br />\n";
Label1.Text += "<ul>\n";
foreach (Yahoo.jp.WebSearchResponse.ResultType item in res.Result)
{
Label1.Text += "<li><a href=\"" + item.ClickUrl + "\">" +
item.Title + "</a>";
}
Label1.Text += "</ul>\n";
}
}
</script>
<html xmlns="http://www.w3.org/1999/xhtml" >
<head runat="server">
<title>Yahoo!ウェブ検索Webサービスのサンプル</title>
</head>
<body>
<form id="form1" runat="server">
<div>
<asp:TextBox ID="TextBox1" runat="server"></asp:TextBox>
<asp:Button ID="Button1" runat="server"
OnClick="Button1_Click" Text="検索" /><br />
<br />
<asp:Label ID="Label1" runat="server"
EnableViewState="False"></asp:Label>
</div>
</form>
<!-- Begin Yahoo! JAPAN Web Services Attribution Snippet -->
<span style="margin:15px 15px 15px 15px">
<a href="http://developer.yahoo.co.jp/about">Webサービス by Yahoo! JAPAN</a>
</span>
<!-- End Yahoo! JAPAN Web Services Attribution Snippet -->
</body>
</html>
|
Yahoo!ウェブ検索Webサービスではリクエストの送信にHTTP GETを使用しますので、まずはWebサービスサーバーにデータを送信するためのURLを構築します。
次にHttpWebRequestとHttpWebResponseクラスを使用してサーバーにアクセスし、結果として返されるXMLデータを取得します。
サーバーから返されたXMLデータは、XmlSerializer.Deserializeメソッドにより、xsd.exeで作成されたResultSetクラスに逆シリアル化されます。こうして作成されたResultSetオブジェクトを参照すれば、結果を簡単に取得できるようになります。
参考:
xsd.exeでDataSetから派生したクラスを作成した場合
xsd.exeでクラスを作成するときに「/c」ではなく「/d」としてDataSetから派生したクラスを作成した場合は、DataSet.ReadXmlメソッドを使ってXMLデータを読み込みます。
この例は、自由区/Webサービス紹介/Yahoo!検索Webサービス/ウェブ検索/コード/DataSetの派生クラスを使用/C#と自由区/Webサービス紹介/Yahoo!検索Webサービス/ウェブ検索/コード/DataSetの派生クラスを使用/VB.NETで紹介しています。これは先に示したサンプルと全く同じことをするものです。
XmlDocumentクラスでXMLデータを解析する
xsd.exeで作成したクラスを使わずに、Webサービスが返したXMLデータを解析するには、XmlDocumentクラスを使うのが適当でしょう。上記のサンプルと同じことをxsd.exeで作成したクラスを使わずに、XmlDocumentクラスにより解析する例を自由区/Webサービス紹介/Yahoo!検索Webサービス/ウェブ検索/コード/XmlDocumentで解析/C#と自由区/Webサービス紹介/Yahoo!検索Webサービス/ウェブ検索/コード/XmlDocumentで解析/VB.NETで紹介しています。
Yahoo!ウェブ検索Webサービスの使い方 †
Yahoo!ウェブ検索Webサービスの使い方をもう少し詳しく説明しましょう。リクエストパラメータとレスポンスフィールドに関する説明はYahoo!デベロッパーネットワークにありますので、ここでは具体的なコードを示します。
自由区/Webサービス紹介/Yahoo!検索Webサービス/ウェブ検索/コード/C#と自由区/Webサービス紹介/Yahoo!検索Webサービス/ウェブ検索/コード/VB.NETで紹介しているWebアプリケーションでは、検索に使うクエリー文字のほかに、指定検索の種類(クエリー文字をすべて含むか、いずれかを含むか、文章として含むか)、表示件数、ファイル形式(HTML、PDFなど)、アダルトコンテンツの表示、類似の結果の表示、日本語のページのみの表示、日本にあるウェブサイトのみの表示、検索するドメインといったオプションを指定して検索できます。また、結果も詳しく(要約、キャッシュ情報、更新日、MIMEタイプなど)表示しています。
最後にYahoo!ウェブ検索Webサービスを使用する際の注意点を幾つか挙げます。
Yahoo!デベロッパーネットワークにはlanguageリクエストパラメータのデフォルトは「ja」と書いてありますが、実際にはデフォルトは「すべての言語」であるようです。上のサンプルで「日本語のページのみ」を選択するとlanguageリクエストパラメータをjaとしますが、何も指定しない時と比べて明らかに結果が異なります。
また、Yahoo!のWebサービスを利用するすべてのサイトやアプリケーションにはクレジットを表示する必要があることにも注意してください(上のサンプルでは表示しています)。詳しくは、Yahoo!デベロッパーネットワークをご覧ください。
Webサービスで検索した結果と、実際にYahoo! JAPANで検索した結果が若干違いますが、これがなぜなのかは分かりません。Yahoo!の提供するWebサービスの一つである画像検索Webサービスなどは検索結果が大きく異なり、Webサービスで検索した方が圧倒的に検索件数が少なくなります。本家米国のYahoo!でも同様のWebサービスを提供していますが、この米国のWebサービス「Image Search Web Services」を利用した時の結果はYahoo! JAPANで実際に検索した結果に近くなります。少なくとも画像検索Webサービスについていえば、Yahoo! JAPANのWebサービスを使うよりも、米国Yahoo!のWebサービスを使った方がよさそうです。
ちなみにYahoo! JAPANのウェブ検索Webサービスでは検索結果を最大50件までしか取得できませんが、米国Yahoo!のWebサービスでは100件まで取得できます。(画像、動画の検索では、両方とも50件までです。)
コメント †