jetty-9 - HTTP client: added HttpClient.POST() utility method.
This commit is contained in:
parent
bfe08d1a99
commit
92c93e2868
|
@ -44,6 +44,7 @@ import org.eclipse.jetty.client.api.CookieStore;
|
|||
import org.eclipse.jetty.client.api.Destination;
|
||||
import org.eclipse.jetty.client.api.Request;
|
||||
import org.eclipse.jetty.client.api.Response;
|
||||
import org.eclipse.jetty.http.HttpMethod;
|
||||
import org.eclipse.jetty.io.ByteBufferPool;
|
||||
import org.eclipse.jetty.io.EndPoint;
|
||||
import org.eclipse.jetty.io.MappedByteBufferPool;
|
||||
|
@ -223,6 +224,16 @@ public class HttpClient extends AggregateLifeCycle
|
|||
return newRequest(uri).send();
|
||||
}
|
||||
|
||||
public Request POST(String uri)
|
||||
{
|
||||
return POST(URI.create(uri));
|
||||
}
|
||||
|
||||
public Request POST(URI uri)
|
||||
{
|
||||
return newRequest(uri).method(HttpMethod.POST);
|
||||
}
|
||||
|
||||
public Request newRequest(String host, int port)
|
||||
{
|
||||
return newRequest(URI.create(address("http", host, port)));
|
||||
|
@ -280,7 +291,7 @@ public class HttpClient extends AggregateLifeCycle
|
|||
return new ArrayList<Destination>(destinations.values());
|
||||
}
|
||||
|
||||
public void send(Request request, Response.Listener listener)
|
||||
protected void send(Request request, Response.Listener listener)
|
||||
{
|
||||
String scheme = request.scheme().toLowerCase();
|
||||
if (!Arrays.asList("http", "https").contains(scheme))
|
||||
|
|
|
@ -18,6 +18,9 @@
|
|||
|
||||
package org.eclipse.jetty.client;
|
||||
|
||||
import java.io.UnsupportedEncodingException;
|
||||
import java.net.URLEncoder;
|
||||
import java.nio.charset.UnsupportedCharsetException;
|
||||
import java.util.Enumeration;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
|
@ -29,13 +32,16 @@ import org.eclipse.jetty.client.api.Connection;
|
|||
import org.eclipse.jetty.client.api.ContentProvider;
|
||||
import org.eclipse.jetty.client.api.Request;
|
||||
import org.eclipse.jetty.client.api.Response;
|
||||
import org.eclipse.jetty.client.util.StringContentProvider;
|
||||
import org.eclipse.jetty.http.HttpCookie;
|
||||
import org.eclipse.jetty.http.HttpFields;
|
||||
import org.eclipse.jetty.http.HttpHeader;
|
||||
import org.eclipse.jetty.http.HttpMethod;
|
||||
import org.eclipse.jetty.http.HttpVersion;
|
||||
import org.eclipse.jetty.http.MimeTypes;
|
||||
import org.eclipse.jetty.io.AbstractConnection;
|
||||
import org.eclipse.jetty.io.EndPoint;
|
||||
import org.eclipse.jetty.util.Fields;
|
||||
import org.eclipse.jetty.util.log.Log;
|
||||
import org.eclipse.jetty.util.log.Logger;
|
||||
|
||||
|
@ -120,6 +126,7 @@ public class HttpConnection extends AbstractConnection implements Connection
|
|||
if (request.idleTimeout() <= 0)
|
||||
request.idleTimeout(client.getIdleTimeout());
|
||||
|
||||
HttpMethod method = request.method();
|
||||
HttpVersion version = request.version();
|
||||
HttpFields headers = request.headers();
|
||||
ContentProvider content = request.content();
|
||||
|
@ -127,7 +134,64 @@ public class HttpConnection extends AbstractConnection implements Connection
|
|||
// Make sure the path is there
|
||||
String path = request.path();
|
||||
if (path.matches("\\s*"))
|
||||
request.path("/");
|
||||
{
|
||||
path = "/";
|
||||
request.path(path);
|
||||
}
|
||||
|
||||
Fields fields = request.params();
|
||||
if (!fields.isEmpty())
|
||||
{
|
||||
StringBuilder params = new StringBuilder();
|
||||
for (Iterator<Fields.Field> fieldIterator = fields.iterator(); fieldIterator.hasNext();)
|
||||
{
|
||||
Fields.Field field = fieldIterator.next();
|
||||
String[] values = field.values();
|
||||
for (int i = 0; i < values.length; ++i)
|
||||
{
|
||||
if (i > 0)
|
||||
params.append("&");
|
||||
params.append(field.name()).append("=");
|
||||
params.append(urlEncode(values[i]));
|
||||
}
|
||||
if (fieldIterator.hasNext())
|
||||
params.append("&");
|
||||
}
|
||||
|
||||
// Behave as a GET, adding the params to the path, if it's a POST with some content
|
||||
if (method == HttpMethod.POST && request.content() != null)
|
||||
method = HttpMethod.GET;
|
||||
|
||||
switch (method)
|
||||
{
|
||||
case GET:
|
||||
{
|
||||
path += "?";
|
||||
path += params.toString();
|
||||
request.path(path);
|
||||
break;
|
||||
}
|
||||
case POST:
|
||||
{
|
||||
request.header(HttpHeader.CONTENT_TYPE.asString(), MimeTypes.Type.FORM_ENCODED.asString());
|
||||
request.content(new StringContentProvider(params.toString()));
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// If we are HTTP 1.1, add the Host header
|
||||
if (version.getVersion() > 10)
|
||||
{
|
||||
if (!headers.containsKey(HttpHeader.HOST.asString()))
|
||||
{
|
||||
String value = request.host();
|
||||
int port = request.port();
|
||||
if (port > 0)
|
||||
value += ":" + port;
|
||||
headers.put(HttpHeader.HOST, value);
|
||||
}
|
||||
}
|
||||
|
||||
// Add content headers
|
||||
if (content != null)
|
||||
|
@ -181,18 +245,18 @@ public class HttpConnection extends AbstractConnection implements Connection
|
|||
headers.put(HttpHeader.ACCEPT_ENCODING, value.toString());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// If we are HTTP 1.1, add the Host header
|
||||
if (version.getVersion() > 10)
|
||||
private String urlEncode(String value)
|
||||
{
|
||||
String encoding = "UTF-8";
|
||||
try
|
||||
{
|
||||
if (!headers.containsKey(HttpHeader.HOST.asString()))
|
||||
{
|
||||
String value = request.host();
|
||||
int port = request.port();
|
||||
if (port > 0)
|
||||
value += ":" + port;
|
||||
headers.put(HttpHeader.HOST, value);
|
||||
}
|
||||
return URLEncoder.encode(value, encoding);
|
||||
}
|
||||
catch (UnsupportedEncodingException e)
|
||||
{
|
||||
throw new UnsupportedCharsetException(encoding);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -18,7 +18,6 @@
|
|||
|
||||
package org.eclipse.jetty.client;
|
||||
|
||||
import java.net.URLEncoder;
|
||||
import java.nio.ByteBuffer;
|
||||
import java.util.Collections;
|
||||
import java.util.Iterator;
|
||||
|
@ -33,7 +32,6 @@ import org.eclipse.jetty.io.ByteBufferPool;
|
|||
import org.eclipse.jetty.io.EndPoint;
|
||||
import org.eclipse.jetty.util.BufferUtil;
|
||||
import org.eclipse.jetty.util.Callback;
|
||||
import org.eclipse.jetty.util.Fields;
|
||||
import org.eclipse.jetty.util.log.Log;
|
||||
import org.eclipse.jetty.util.log.Logger;
|
||||
|
||||
|
@ -95,27 +93,7 @@ public class HttpSender
|
|||
{
|
||||
case NEED_INFO:
|
||||
{
|
||||
String path = request.path();
|
||||
Fields fields = request.params();
|
||||
if (!fields.isEmpty())
|
||||
{
|
||||
path += "?";
|
||||
for (Iterator<Fields.Field> fieldIterator = fields.iterator(); fieldIterator.hasNext();)
|
||||
{
|
||||
Fields.Field field = fieldIterator.next();
|
||||
String[] values = field.values();
|
||||
for (int i = 0; i < values.length; ++i)
|
||||
{
|
||||
if (i > 0)
|
||||
path += "&";
|
||||
path += field.name() + "=";
|
||||
path += URLEncoder.encode(values[i], "UTF-8");
|
||||
}
|
||||
if (fieldIterator.hasNext())
|
||||
path += "&";
|
||||
}
|
||||
}
|
||||
info = new HttpGenerator.RequestInfo(request.version(), request.headers(), contentLength, request.method().asString(), path);
|
||||
info = new HttpGenerator.RequestInfo(request.version(), request.headers(), contentLength, request.method().asString(), request.path());
|
||||
break;
|
||||
}
|
||||
case NEED_HEADER:
|
||||
|
|
|
@ -0,0 +1,34 @@
|
|||
//
|
||||
// ========================================================================
|
||||
// Copyright (c) 1995-2012 Mort Bay Consulting Pty. Ltd.
|
||||
// ------------------------------------------------------------------------
|
||||
// All rights reserved. This program and the accompanying materials
|
||||
// are made available under the terms of the Eclipse Public License v1.0
|
||||
// and Apache License v2.0 which accompanies this distribution.
|
||||
//
|
||||
// The Eclipse Public License is available at
|
||||
// http://www.eclipse.org/legal/epl-v10.html
|
||||
//
|
||||
// The Apache License v2.0 is available at
|
||||
// http://www.opensource.org/licenses/apache2.0.php
|
||||
//
|
||||
// You may elect to redistribute this code under either of these licenses.
|
||||
// ========================================================================
|
||||
//
|
||||
|
||||
package org.eclipse.jetty.client.util;
|
||||
|
||||
import java.nio.charset.Charset;
|
||||
|
||||
public class StringContentProvider extends BytesContentProvider
|
||||
{
|
||||
public StringContentProvider(String content)
|
||||
{
|
||||
this(content, "UTF-8");
|
||||
}
|
||||
|
||||
public StringContentProvider(String content, String encoding)
|
||||
{
|
||||
super(content.getBytes(Charset.forName(encoding)));
|
||||
}
|
||||
}
|
|
@ -43,6 +43,7 @@ import org.eclipse.jetty.client.api.Destination;
|
|||
import org.eclipse.jetty.client.api.Request;
|
||||
import org.eclipse.jetty.client.api.Response;
|
||||
import org.eclipse.jetty.client.api.Result;
|
||||
import org.eclipse.jetty.client.util.BytesContentProvider;
|
||||
import org.eclipse.jetty.http.HttpCookie;
|
||||
import org.eclipse.jetty.server.handler.AbstractHandler;
|
||||
import org.eclipse.jetty.toolchain.test.MavenTestingUtils;
|
||||
|
@ -214,6 +215,67 @@ public class HttpClientTest extends AbstractHttpClientServerTest
|
|||
Assert.assertEquals(value11 + value12 + value2, content);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void test_POST_WithParameters() throws Exception
|
||||
{
|
||||
final String paramName = "a";
|
||||
final String paramValue = "\u20AC";
|
||||
start(new AbstractHandler()
|
||||
{
|
||||
@Override
|
||||
public void handle(String target, org.eclipse.jetty.server.Request baseRequest, HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException
|
||||
{
|
||||
baseRequest.setHandled(true);
|
||||
String value = request.getParameter(paramName);
|
||||
if (paramValue.equals(value))
|
||||
{
|
||||
response.setCharacterEncoding("UTF-8");
|
||||
response.setContentType("text/plain");
|
||||
response.getOutputStream().print(value);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
ContentResponse response = client.POST(scheme + "://localhost:" + connector.getLocalPort())
|
||||
.param(paramName, paramValue).send().get(5, TimeUnit.SECONDS);
|
||||
|
||||
Assert.assertNotNull(response);
|
||||
Assert.assertEquals(200, response.status());
|
||||
Assert.assertEquals(paramValue, new String(response.content(), "UTF-8"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void test_POST_WithParameters_WithContent() throws Exception
|
||||
{
|
||||
final byte[] content = {0, 1, 2, 3};
|
||||
final String paramName = "a";
|
||||
final String paramValue = "\u20AC";
|
||||
start(new AbstractHandler()
|
||||
{
|
||||
@Override
|
||||
public void handle(String target, org.eclipse.jetty.server.Request baseRequest, HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException
|
||||
{
|
||||
baseRequest.setHandled(true);
|
||||
String value = request.getParameter(paramName);
|
||||
if (paramValue.equals(value))
|
||||
{
|
||||
response.setCharacterEncoding("UTF-8");
|
||||
response.setContentType("text/plain");
|
||||
response.getOutputStream().write(content);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
ContentResponse response = client.POST(scheme + "://localhost:" + connector.getLocalPort() + "/?b=1")
|
||||
.param(paramName, paramValue)
|
||||
.content(new BytesContentProvider(content))
|
||||
.send().get(5, TimeUnit.SECONDS);
|
||||
|
||||
Assert.assertNotNull(response);
|
||||
Assert.assertEquals(200, response.status());
|
||||
Assert.assertArrayEquals(content, response.content());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void test_QueuedRequest_IsSent_WhenPreviousRequestSucceeded() throws Exception
|
||||
{
|
||||
|
|
|
@ -96,6 +96,13 @@ public class Usage
|
|||
Assert.assertEquals(200, response.status());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testPOSTWithParams() throws Exception
|
||||
{
|
||||
HttpClient client = new HttpClient();
|
||||
client.POST("http://localhost:8080").param("a", "\u20AC").send();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testRequestListener() throws Exception
|
||||
{
|
||||
|
|
Loading…
Reference in New Issue