New APIs in RequestBuilder to add the following three methods:
void setRequestData(String)
void setCallback(RequestCallback)
Request send()
Calling each of these methods in turn will have a similar effect to calling the existing method:
sendRequest(String, RequestCallback)
The main difference is that the additional setters allow the data to be stored in the RequestBuilder object. This change will enable RPC to return a "ready to go" RequestBuilder for a client to tweak.
Review by: bobv
git-svn-id: https://google-web-toolkit.googlecode.com/svn/trunk@2243 8db76d5a-ed1c-0410-87a9-c151d255dfc7
diff --git a/user/src/com/google/gwt/http/client/RequestBuilder.java b/user/src/com/google/gwt/http/client/RequestBuilder.java
index 07ef478..2e6a19c 100644
--- a/user/src/com/google/gwt/http/client/RequestBuilder.java
+++ b/user/src/com/google/gwt/http/client/RequestBuilder.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2007 Google Inc.
+ * Copyright 2008 Google Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not
* use this file except in compliance with the License. You may obtain a copy of
@@ -72,33 +72,37 @@
private static final HTTPRequestImpl httpRequest = (HTTPRequestImpl) GWT.create(HTTPRequestImpl.class);
- /*
+ private RequestCallback callback;
+
+ /**
* Map of header name to value that will be added to the JavaScript
* XmlHttpRequest object before sending a request.
*/
private Map<String, String> headers;
- /*
+ /**
* HTTP method to use when opening an JavaScript XmlHttpRequest object
*/
- private String httpMethod;
+ private final String httpMethod;
- /*
+ /**
* Password to use when opening an JavaScript XmlHttpRequest object
*/
private String password;
- /*
+ private String requestData;
+
+ /**
* Timeout in milliseconds before the request timeouts and fails.
*/
private int timeoutMillis;
- /*
+ /**
* URL to use when opening an JavaScript XmlHttpRequest object.
*/
- private String url;
+ private final String url;
- /*
+ /**
* User to use when opening an JavaScript XmlHttpRequest object
*/
private String user;
@@ -147,48 +151,52 @@
/**
* Sends an HTTP request based on the current builder configuration. If no
* request headers have been set, the header "Content-Type" will be used with
- * a value of "text/plain; charset=utf-8".
+ * a value of "text/plain; charset=utf-8". You must call
+ * {@link #setRequestData(String)} and {@link #setCallback(RequestCallback)}
+ * before calling this method.
+ *
+ * @return a {@link Request} object that can be used to track the request
+ * @throws RequestException if the call fails to initiate
+ * @throws NullPointerException if a request callback has not been set
+ */
+ public Request send() throws RequestException {
+ StringValidator.throwIfNull("callback", callback);
+ return doSend(requestData, callback);
+ }
+
+ /**
+ * Sends an HTTP request based on the current builder configuration with the
+ * specified data and callback. If no request headers have been set, the
+ * header "Content-Type" will be used with a value of "text/plain;
+ * charset=utf-8". This method does not cache <code>requestData</code> or
+ * <code>callback</code>.
*
* @param requestData the data to send as part of the request
* @param callback the response handler to be notified when the request fails
* or completes
* @return a {@link Request} object that can be used to track the request
+ * @throws NullPointerException if <code>callback</code> <code>null</code>
*/
public Request sendRequest(String requestData, RequestCallback callback)
throws RequestException {
+ StringValidator.throwIfNull("callback", callback);
+ return doSend(requestData, callback);
+ }
- if (user == null && password != null) {
- throw new IllegalStateException("A password is set, but no user is set");
- }
+ /**
+ * Sets the response handler for this request. This method <b>must</b> be
+ * called before calling {@link #send()}.
+ *
+ * @param callback the response handler to be notified when the request fails
+ * or completes
+ *
+ * @throws NullPointerException if <code>callback</code> is
+ * <code>null</code>
+ */
+ public void setCallback(RequestCallback callback) {
+ StringValidator.throwIfNull("callback", callback);
- JavaScriptObject xmlHttpRequest = httpRequest.createXmlHTTPRequest();
- String openError;
- if (password != null) {
- openError = XMLHTTPRequest.open(xmlHttpRequest, httpMethod, url, true,
- user, password);
- } else if (user != null) {
- openError = XMLHTTPRequest.open(xmlHttpRequest, httpMethod, url, true,
- user);
- } else {
- openError = XMLHTTPRequest.open(xmlHttpRequest, httpMethod, url, true);
- }
- if (openError != null) {
- RequestPermissionException requestPermissionException = new RequestPermissionException(url);
- requestPermissionException.initCause(new RequestException(openError));
- throw requestPermissionException;
- }
-
- setHeaders(xmlHttpRequest);
-
- Request request = new Request(xmlHttpRequest, timeoutMillis, callback);
-
- String sendError = XMLHTTPRequest.send(xmlHttpRequest, request,
- requestData, callback);
- if (sendError != null) {
- throw new RequestException(sendError);
- }
-
- return request;
+ this.callback = callback;
}
/**
@@ -229,6 +237,16 @@
}
/**
+ * Sets the data to send as part of this request. This method <b>must</b> be
+ * called before calling {@link #send()}.
+ *
+ * @param requestData the data to send as part of the request
+ */
+ public void setRequestData(String requestData) {
+ this.requestData = requestData;
+ }
+
+ /**
* Sets the number of milliseconds to wait for a request to complete. Should
* the request timeout, the
* {@link com.google.gwt.http.client.RequestCallback#onError(Request, Throwable)}
@@ -264,6 +282,49 @@
this.user = user;
}
+ /**
+ * Sends an HTTP request based on the current builder configuration. If no
+ * request headers have been set, the header "Content-Type" will be used with
+ * a value of "text/plain; charset=utf-8".
+ *
+ * @return a {@link Request} object that can be used to track the request
+ * @throws RequestException if the call fails to initiate
+ * @throws NullPointerException if request data has not been set
+ * @throws NullPointerException if a request callback has not been set
+ */
+ private Request doSend(String requestData, RequestCallback callback)
+ throws RequestException {
+ JavaScriptObject xmlHttpRequest = httpRequest.createXmlHTTPRequest();
+ String openError;
+ if (user != null && password != null) {
+ openError = XMLHTTPRequest.open(xmlHttpRequest, httpMethod, url, true,
+ user, password);
+ } else if (user != null) {
+ openError = XMLHTTPRequest.open(xmlHttpRequest, httpMethod, url, true,
+ user);
+ } else {
+ openError = XMLHTTPRequest.open(xmlHttpRequest, httpMethod, url, true);
+ }
+ if (openError != null) {
+ RequestPermissionException requestPermissionException = new RequestPermissionException(
+ url);
+ requestPermissionException.initCause(new RequestException(openError));
+ throw requestPermissionException;
+ }
+
+ setHeaders(xmlHttpRequest);
+
+ Request request = new Request(xmlHttpRequest, timeoutMillis, callback);
+
+ String sendError = XMLHTTPRequest.send(xmlHttpRequest, request,
+ requestData, callback);
+ if (sendError != null) {
+ throw new RequestException(sendError);
+ }
+
+ return request;
+ }
+
/*
* Internal method that actually sets our cached headers on the underlying
* JavaScript XmlHttpRequest object. If there are no headers set, then we set
diff --git a/user/src/com/google/gwt/http/client/StringValidator.java b/user/src/com/google/gwt/http/client/StringValidator.java
index 1ef9e98..ee2b5ca 100644
--- a/user/src/com/google/gwt/http/client/StringValidator.java
+++ b/user/src/com/google/gwt/http/client/StringValidator.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2006 Google Inc.
+ * Copyright 2008 Google Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not
* use this file except in compliance with the License. You may obtain a copy of
@@ -57,11 +57,11 @@
* Throws a {@link NullPointerException} if the value is <code>null</code>.
*
* @param name the name of the value, used in error messages
- * @param value the string value that needs to be validated
+ * @param value the value that needs to be validated
*
* @throws NullPointerException if the value is <code>null</code>
*/
- public static void throwIfNull(String name, String value) {
+ public static void throwIfNull(String name, Object value) {
if (null == value) {
throw new NullPointerException(name + " cannot be null");
}
diff --git a/user/test/com/google/gwt/http/client/RequestBuilderTest.java b/user/test/com/google/gwt/http/client/RequestBuilderTest.java
index bedda28..5a7d84e 100644
--- a/user/test/com/google/gwt/http/client/RequestBuilderTest.java
+++ b/user/test/com/google/gwt/http/client/RequestBuilderTest.java
@@ -144,6 +144,51 @@
* Test method for
* {@link com.google.gwt.http.client.RequestBuilder#sendRequest(java.lang.String, com.google.gwt.http.client.RequestCallback)}.
*/
+ public void testSend_GET() throws RequestException {
+ delayTestFinish(TEST_FINISH_DELAY);
+
+ RequestBuilder builder = new RequestBuilder(RequestBuilder.GET,
+ getTestBaseURL() + "send_GET");
+ builder.setCallback(new RequestCallback() {
+ public void onError(Request request, Throwable exception) {
+ fail(exception.getMessage());
+ }
+
+ public void onResponseReceived(Request request, Response response) {
+ assertEquals(200, response.getStatusCode());
+ finishTest();
+ }
+ });
+ builder.send();
+ }
+
+ /**
+ * Test method for {@link com.google.gwt.http.client.RequestBuilder#send()}.
+ */
+ public void testSend_POST() throws RequestException {
+ delayTestFinish(TEST_FINISH_DELAY);
+
+ RequestBuilder builder = new RequestBuilder(RequestBuilder.POST,
+ getTestBaseURL() + "sendRequest_POST");
+ builder.setHeader("Content-Type", "application/x-www-form-urlencoded");
+ builder.setCallback(new RequestCallback() {
+ public void onError(Request request, Throwable exception) {
+ fail(exception.getMessage());
+ }
+
+ public void onResponseReceived(Request request, Response response) {
+ assertEquals(200, response.getStatusCode());
+ finishTest();
+ }
+ });
+ builder.setRequestData("method=test+request");
+ builder.send();
+ }
+
+ /**
+ * Test method for
+ * {@link com.google.gwt.http.client.RequestBuilder#sendRequest(java.lang.String, com.google.gwt.http.client.RequestCallback)}.
+ */
public void testSendRequest_GET() throws RequestException {
delayTestFinish(TEST_FINISH_DELAY);
@@ -183,22 +228,40 @@
});
}
+ public void testSetCallback() {
+ RequestBuilder builder = new RequestBuilder(RequestBuilder.GET,
+ getTestBaseURL());
+ try {
+ builder.setCallback(null);
+ fail("Expected NullPointerException");
+ } catch (NullPointerException expected) {
+ }
+ }
+
public void testSetPassword() {
RequestBuilder builder = new RequestBuilder(RequestBuilder.GET,
getTestBaseURL());
try {
builder.setPassword(null);
- } catch (NullPointerException ex) {
- // Correct behavior, exception was thrown
+ fail("Expected NullPointerException");
+ } catch (NullPointerException expected) {
}
try {
builder.setPassword("");
- } catch (IllegalArgumentException ex) {
- // Correct behavior, exception was thrown
+ fail("Expected IllegalArgumentException");
+ } catch (IllegalArgumentException expected) {
}
}
+ public void testSetRequestData() {
+ RequestBuilder builder = new RequestBuilder(RequestBuilder.GET,
+ getTestBaseURL());
+ // Legal.
+ builder.setRequestData(null);
+ builder.setRequestData("");
+ }
+
/**
* Test method for
* {@link com.google.gwt.http.client.RequestBuilder#setHeader(java.lang.String, java.lang.String)}.
@@ -219,29 +282,25 @@
try {
builder.setHeader(null, "bar");
fail("setRequestHeader(null, \"bar\")");
- } catch (NullPointerException ex) {
- // purposely ignored
+ } catch (NullPointerException expected) {
}
try {
builder.setHeader("", "bar");
fail("setRequestHeader(\"\", \"bar\")");
- } catch (IllegalArgumentException ex) {
- // purposely ignored
+ } catch (IllegalArgumentException expected) {
}
try {
builder.setHeader("foo", null);
fail("setRequestHeader(\"foo\", null)");
- } catch (NullPointerException ex) {
- // purposely ignored
+ } catch (NullPointerException expected) {
}
try {
builder.setHeader("foo", "");
fail("setRequestHeader(\"foo\", \"\")");
- } catch (IllegalArgumentException ex) {
- // purposely ignored
+ } catch (IllegalArgumentException expected) {
}
delayTestFinish(TEST_FINISH_DELAY);
@@ -326,14 +385,14 @@
getTestBaseURL());
try {
builder.setUser(null);
- } catch (NullPointerException ex) {
- // Correct behavior, exception was thrown
+ fail("Expected NullPointerException");
+ } catch (NullPointerException expected) {
}
try {
builder.setUser("");
- } catch (IllegalArgumentException ex) {
- // Correct behavior, exception was thrown
+ fail("Expected IllegalArgumentException");
+ } catch (IllegalArgumentException expected) {
}
}
}
diff --git a/user/test/com/google/gwt/http/server/RequestBuilderTestServlet.java b/user/test/com/google/gwt/http/server/RequestBuilderTestServlet.java
index 38b93dd..f0efd75 100644
--- a/user/test/com/google/gwt/http/server/RequestBuilderTestServlet.java
+++ b/user/test/com/google/gwt/http/server/RequestBuilderTestServlet.java
@@ -51,6 +51,10 @@
} else {
response.setStatus(HttpServletResponse.SC_BAD_REQUEST);
}
+ } else if (pathInfo.equals(getPathInfoBase() + "send_GET")) {
+ response.setStatus(HttpServletResponse.SC_OK);
+ response.getWriter().write("<html><body>hello</body></html>");
+ response.setContentType("text/html");
} else if (pathInfo.equals(getPathInfoBase() + "sendRequest_GET")) {
response.setStatus(HttpServletResponse.SC_OK);
response.getWriter().write("<html><body>hello</body></html>");