WebRequest、WebResponse


有時你並非想取得一個頁面,在頁面上作些操作(例如填寫表單或按下超鏈結)後看看下一個頁面的反應,有時你是想直接對某個頁面發送請求,看看該頁面的回應。例如,你也許想直接對 使用 HtmlUnit 中的add.do作測試,而非透過add.jsp來對add.do作測試。

你可以直接使用WebRequest來發出HTTP請求。例如:
package test.cc.openhome;

import static org.junit.Assert.*;

import java.net.URL;
import java.util.Arrays;

import org.junit.Before;
import org.junit.After;
import org.junit.Test;

import com.gargoylesoftware.htmlunit.BrowserVersion;
import com.gargoylesoftware.htmlunit.HttpMethod;
import com.gargoylesoftware.htmlunit.WebClient;
import com.gargoylesoftware.htmlunit.WebRequest;
import com.gargoylesoftware.htmlunit.html.HtmlPage;
import com.gargoylesoftware.htmlunit.util.NameValuePair;

public class AddJSPTest {
private WebClient webClient;
private WebRequest request;

@Before
public void setUp() throws Exception {
webClient = new WebClient(BrowserVersion.FIREFOX_3);
// 建立請求物件,請求方法為 POST
request = new WebRequest(
new URL("http://localhost:8080/BookmarkOnline/add.do"),
HttpMethod.POST);
request.setCharset("UTF-8");
}

@After
public void tearDown() throws Exception {
webClient.closeAllWindows();
}

@Test
public void testError() throws Exception {
// 沒有請求參數的情況
HtmlPage page = webClient.getPage(request);
assertEquals("新增書籤失敗",
page.getElementsByTagName("h1")
.item(0).getFirstChild().getNodeValue());
}

@Test
public void testParameters() throws Exception {
// 請求參數不足的情況
String title = "測試";
request.setRequestParameters(
Arrays.asList(new NameValuePair("title", title)));
HtmlPage page = webClient.getPage(request);

assertEquals("新增書籤失敗",
page.getElementsByTagName("h1")
.item(0).getFirstChild().getNodeValue());
assertEquals(title,
page.getElementsByName("title")
.get(0).getAttribute("value"));
}

@Test
public void testSubmitSuccess() throws Exception {
// 發送成功的情況
request.setRequestParameters(Arrays.asList(
new NameValuePair("url", "http://test"),
new NameValuePair("title", "測試"),
new NameValuePair("category", "testCategory")));
HtmlPage page = webClient.getPage(request);

assertEquals("新增書籤成功", page.getTitleText());
}
}

如上所示,你可以使用WebRequest指定較多有關於HTTP的細節,如果你對回應有更多想處理的細節,而非透過HtmlPage的DOM相關API來取得結果,則可以使用WebResponse。例如:
WebResponse resp = webClient.loadWebResponse(request);

可以將webClient.getPage()改使用webClient.loadWebResponse(),這會請求伺服端,並將回應以WebResponse包裝傳回,你可以從WebResponse上取得更多資訊,例如使用getContentAsStream()等方法。

如果這樣的彈性仍還不夠,HtmlUnit底層使用的是 HttpClient,你可以直接使用HttpClient的相關API來進行更低階的HTTP操作。