2007 年 6 月
簡介
有時候,沒有取代電線的選擇。在使用使用 Google Data API 等網路服務的軟體編寫這類軟體時,更是如此,因為有許多作業涉及發出 HTTP 要求。 當所有其他條件都失敗時,您可以查看實際傳輸和接收的位元組,驗證程式是否如預期運作。Google Data API 的許多用戶端程式庫都設有顯示 HTTP 流量的偵錯模式。如果您無法存取 SreShark 或 Fiddler 這類封包剪接程式,這項功能就特別實用。
我無法計算我的程式不正確的出現次數,只會在檢查封包追蹤記錄中發現多餘的換行字元或名稱有誤的 HTTP 標頭。您在不查看 HTTP 流量的情況下,針對網路服務進行程式設計,就如同嘗試讓眼睛閉合的針線一樣。
但是,您可能會在自己遇到封包加密工具無法使用或不足以處理加密封包的情況下遇到自己。只要運用程式化的紀錄機制,您就能克服這項限制。只要運用這些記錄設備,您就能看到部分交換資料 (但不是全部的資料),即使是加密的 HTTPS 資料或遠端執行的程式碼也一樣。
在本文中,我已使用適用於 Java、.NET 和 Python 的 Google Data API 用戶端程式庫,以 3 種語言編寫範例診斷程式碼。在每個範例中,我開啟記錄或偵錯功能,使用用戶端登入資訊進行驗證,然後取得 Google 試算表的清單並列印這些標題。
Java
您可以使用 java.util.logging
類別,為用戶端程式庫中的幾個重要物件設定記錄層級 (並因此公開流量資料)。在以下範例中,我選擇查看 HTTP 標頭和 XML 剖析器的活動,以完整掌握線路的運作情形。
Google Data Java 用戶端程式庫有獨立的類別來處理 HTTP 要求和 XML 剖析;因此,我必須建立兩個記錄器物件,每個類別各一個:com.google.gdata.client.http.HttpGDataRequest
會處理 HTTP 流量,而 com.google.gdata.util.XmlParser
則負責處理 XML 剖析。
記錄器執行個體會記錄 HttpGDataRequest
和 XmlParser
的活動,而您可以控制每個記錄器輸出內容的細節層級。本示範選擇的是 HttpGDataRequest
和 XmlParser
物件產生的「所有」事件。
建立並設定記錄器後,我需要告知他們收到班級收到事件時該怎麼做。目前,我想將所有記錄資訊寫入主控台,所以建立 ConsoleHandler
並將其加入兩個記錄器。
以下是我的程式碼範例:
import com.google.gdata.client.spreadsheet.*;
import com.google.gdata.data.spreadsheet.*;
import com.google.gdata.util.*;
import java.io.*;
import java.net.URL;
import java.util.*;
import java.util.logging.*;
public class PrintSpreadsheetsWithLogging {
public static void main(String [] args) throws AuthenticationException,
ServiceException, IOException {
// Configure the logging mechanisms.
Logger httpLogger = Logger.getLogger("com.google.gdata.client.http.HttpGDataRequest");
httpLogger.setLevel(Level.ALL);
Logger xmlLogger = Logger.getLogger("com.google.gdata.util.XmlParser");
xmlLogger.setLevel(Level.ALL);
// Create a log handler which prints all log events to the console.
ConsoleHandler logHandler = new ConsoleHandler();
logHandler.setLevel(Level.ALL);
httpLogger.addHandler(logHandler);
xmlLogger.addHandler (logHandler);
SpreadsheetService service = new SpreadsheetService("testing-loggingExampleApp-1");
service.setUserCredentials(email, password);
// Get a list of your spreadsheets.
URL metafeedUrl = new URL("http://spreadsheets.google.com/feeds/spreadsheets/private/full ");
SpreadsheetFeed feed = service.getFeed(metafeedUrl, SpreadsheetFeed.class);
// Print the title of each spreadsheet.
List spreadsheets = feed.getEntries();
for (int i = 0; i < spreadsheets.size(); i++) {
SpreadsheetEntry entry = (SpreadsheetEntry)spreadsheets.get(i);
System.out.println("\t" + entry.getTitle().getPlainText());
}
}
}
執行這個程式時,您會在主控台中看到類似的效果 (我減少一些較不有趣的部分):
Jun 7, 2007 10:24:50 AM ...HttpGDataRequest setPrivateHeader FINER: Authorization: <Not Logged> Jun 7, 2007 10:24:50 AM ...HttpGDataRequest setHeader FINER: User-Agent: ... ... Jun 7, 2007 10:25:20 AM ...HttpGDataRequest execute FINE: 200 OK Jun 7, 2007 10:25:20 AM ...HttpGDataRequest execute FINER: Date: Thu, 07 Jun 2007 17:25:24 GMT Jun 7, 2007 10:25:20 AM ...HttpGDataRequest execute FINER: null: HTTP/1.1 200 OK Jun 7, 2007 10:25:20 AM ...HttpGDataRequest execute FINER: Content-Type: application/atom+xml; charset=UTF-8 Jun 7, 2007 10:25:20 AM ...HttpGDataRequest execute FINER: Last-Modified: Thu, 07 Jun 2007 17:25:22 GMT ... Jun 7, 2007 10:25:20 AM ...XmlParser startElement FINE: Start element id Jun 7, 2007 10:25:20 AM ...XmlParser endElement FINE: End element id ... Jun 7, 2007 10:25:20 AM ...XmlParser startElement FINE: Start element title Jun 7, 2007 10:25:20 AM ...XmlParser startElement FINER: Attribute type='text' Jun 7, 2007 10:25:20 AM ...XmlParser endElement FINE: End element title ... Jun 7, 2007 10:25:20 AM ...XmlParser endElement FINE: End element entry ... Jun 7, 2007 10:25:20 AM ...XmlParser endElement FINE: End element feed
這些記錄可能會變得相當龐大,因此建議您設定記錄器層級的選項。您也可以建立 FileHandler
而非 ConsoleHandler
,以便儲存記錄資料以供日後使用。
當然,如果 Java 不是您的行李,您可以試試 .NET。
.NET
如要擷取 .NET 用戶端程式庫中的 HTTP 流量,您可以將用戶端的預設要求工廠替換為 GDataLoggingRequestFactory
。
.NET 程式庫中的 HTTP 要求是由每個 Service 物件內的 GDataRequestFactory
建立。一般要求工廠不會執行任何記錄,但 GDataLoggingRequestFactory
是 GDataRequestFactory
的子類別,並內建記錄功能。您可以設定 CombinedFileName
來指定記錄檔的完整路徑。
設定要求工廠之後,您必須設定服務物件的 RequestFactory
,以替換要求物件的服務工廠。您的程式碼可能如下:
using System;
using Google.GData.Client;
using Google.GData.Extensions;
using Google.GData.Spreadsheets;
namespace LogginTest
{
class Program
{
static void Main(string[] args)
{
SpreadsheetsService service = new SpreadsheetsService("-exampleApp-1");
service.setUserCredentials(email, password);
Google.GData.Client.GDataLoggingRequestFactory factory = new GDataLoggingRequestFactory("wise", "SpreadsheetsLoggingTest");
factory.MethodOverride = true;
factory.CombinedLogFileName = "c:\\temp\\xmllog.log";
Console.WriteLine("Log file name:" + factory.CombinedLogFileName);
service.RequestFactory = factory;
SpreadsheetQuery query = new SpreadsheetQuery();
SpreadsheetFeed feed = service.Query(query);
Console.WriteLine("Your spreadsheets:");
foreach (SpreadsheetEntry entry in feed.Entries)
{
Console.WriteLine(entry.Title.Text);
}
Console.ReadKey();
}
}
}
產生的紀錄檔包含 XML 要求和回應。以下是使用 tidy 格式化的縮寫範例。
<?xml version='1.0' encoding='utf-8'?> <feed xmlns='http://www.w3.org/2005/Atom' xmlns:openSearch='http://a9.com/-/spec/opensearchrss/1.0/'> <id> http://spreadsheets.google.com/feeds/spreadsheets/private/full</id> <updated>2007-06-07T22:05: 02.674Z</updated> <link rel='self' type='application/atom+xml' href='http://spreadsheets.google.com/feeds/spreadsheets/private/full'> </link> ... <entry> <updated>2007-03-28T17:28:57.250Z</updated> <category scheme=' http://schemas.google.com/spreadsheets/2006' term='http://schemas.google.com/spreadsheets/2006#spreadsheet'> <title type='text'>events</title> <content type='text'>events</content> ... </entry> <entry> <updated>2007-05-25T22:11:08.200Z</updated> <category scheme=' http://schemas.google.com/spreadsheets/2006' term='http://schemas.google.com/spreadsheets/2006#spreadsheet'> </category> <title type='text'>UnitTest</title> <content type='text'>UnitTest</content> ... </entry> ... </feed>
但也許您會實際使用指令碼語言,希望使用 Python。
Python
如要擷取 Python 用戶端程式庫中的 HTTP 流量,您可以在 HTTP 用戶端中開啟偵錯模式,將 HTTP 標頭流量輸出至主控台。服務物件有偵錯成員,可設定為 True。
將偵錯設定為 True 時,會在服務物件的基礎 HTTPRequest
物件中設定偵錯標記。
下方範例說明您在要求試算表清單時,如何回應試算表伺服器傳送的 HTTP 標頭。
#!/usr/bin/python
import gdata.spreadsheet.service
client = gdata.spreadsheet.service.SpreadsheetsService()
client.debug = True
client.ClientLogin(email, password)
feed = client.GetSpreadsheetsFeed()
for entry in feed.entry:
print entry.title.text
主控台中會顯示以下內容:
reply: 'HTTP/1.1 200 OK\r\n' header: Content-Type: application/atom+xml; charset=UTF-8 header: Last-Modified: Thu, 07 Jun 2007 18:22:35 GMT header: Cache-Control: max-age=0, must-revalidate, private header: Transfer-Encoding: chunked ... header: Date: Thu, 07 Jun 2007 18:22:35 GMT header: Server: GFE/1.3
執行其他操作 (例如插入或更新) 時,您會看到與要求控制台有回應的相應要求資料。
結語
這個簡短的教學課程,說明瞭如何將基本記錄功能新增至採用 Google Data API 用戶端程式庫的 Java、.NET 或 Python 程式。如果您需要對 HTTP 交換作業進行偵錯,但無法存取封包監聽器,這些技巧就非常實用。我只用這些例子刮開表面了。這些語言的許多記錄機制都比這裡顯示的內容更有力。如要進一步瞭解記錄或 Google Data API,請參閱以下資源清單。
本文涵蓋的用戶端程式庫如下:
相關知識庫項目:
- 如何在 Java 用戶端程式庫中取得 HTTP 記錄資訊?
- 如何在 .NET 用戶端程式庫中取得 HTTP 紀錄資訊?
- 有哪些良好的 HTTP 偵錯工具?
- 什麼是 Google Sheets API?
討論群組: 我們有許多新功能,日後將陸續推出更多 Google Data API。我們會主動監控這些群組。
如有任何問題或建議,我們十分樂意聽取您的建議。加入討論群組,開始張貼文章。