Skip to content

Commit fae8368

Browse files
committed
completed introduction guide
1 parent 53de63d commit fae8368

File tree

1 file changed

+133
-1
lines changed

1 file changed

+133
-1
lines changed

src/site/apt/request.apt

Lines changed: 133 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -45,4 +45,136 @@ public interface AsyncHandler<T> {
4545
T onCompleted() throws Exception;
4646
}
4747
+-----+
48-
48+
49+
* Creating a Request object
50+
51+
The AsynHttpClient uses the builder pattern when it is time to create Request object. The simplest way consist of:
52+
53+
+-----+
54+
RequestBuilder builder = new RequestBuilder("PUT");
55+
Request request = builder..setUrl("http://")
56+
.addHeader("name", "value")
57+
.setBody(new File("myUpload.avi"))
58+
.build();
59+
AsyncHttpClient client = new AsyncHttpClient();
60+
client.execute(request, new AsyncHandler<...>() {
61+
.....
62+
} );
63+
+-----+
64+
65+
If you need to work with File, the library supports the {{{./zero-bytes-copy.html}zero copy in memory concept}},
66+
e.g the File can be uploaded or downloaded without loading its associated bytes in memory, preventing out of memory
67+
errors in case you need to upload or download many large files. Although the library support the following:
68+
69+
+-----+
70+
Request request = builder.setUrl("http://")
71+
.addHeader("name", "value")
72+
.setBody(myInputStream))
73+
.build();
74+
+-----+
75+
76+
it is discouraged to use <<<InputStream>>> as the library will need to buffer bytes in memory in order to determine
77+
the length of the stream, and instead highly recommended to either use a File or the <<<BodyGenerator>>> API to avoid
78+
loading unnecessary bytes in memory:
79+
80+
+-----+
81+
public interface BodyGenerator {
82+
Body createBody() throws IOException;
83+
}
84+
+-----+
85+
86+
where a Body is defined as:
87+
88+
+-----+
89+
public interface Body {
90+
long getContentLength();
91+
92+
long read(ByteBuffer buffer)
93+
throws IOException;
94+
95+
void close() throws IOException;
96+
}
97+
+-----+
98+
99+
This way the library will never read unnecessary bytes in memory, which could significantly improve the performance
100+
your application.
101+
102+
The <<<RequestBuilder>>> can also be used to create per <<<Request>>> configuration,
103+
like setting a Proxy or request timeout:
104+
105+
+-----+
106+
PerRequestConfig requestConfig = new PerRequestConfig();
107+
requestConfig.setRequestTimeoutInMs(5 * 1000);
108+
requestConfig.setProxy(new ProxyServer(...));
109+
Future responseFuture = client.prepareGet("http://").setPerRequestConfig(requestConfig).execute();
110+
+-----+
111+
112+
* Creating a Response object
113+
114+
The AsyncHandler is typed, e.g you can return any object from the <<<AsyncHandler.onCompleted()>>>. One useful object
115+
of the library is the <<<Response>>> object and it's associate builder. You can incrementally create a <<<Response>>>
116+
object using the <<<ResponseBuilder.accumulate()>>> method:
117+
118+
+-----+
119+
MyAsyncHandler<Response> asyncHandler = new MyAsyncHanfler<Response>() {
120+
private final Response.ResponseBuilder builder = new Response.ResponseBuilder();
121+
122+
public STATE onBodyPartReceived(final HttpResponseBodyPart content) throws Exception {
123+
builder.accumulate(content);
124+
return STATE.CONTINUE;
125+
}
126+
127+
public STATE onStatusReceived(final HttpResponseStatus status) throws Exception {
128+
builder.accumulate(status);
129+
return STATE.CONTINUE;
130+
}
131+
132+
public STATE onHeadersReceived(final HttpResponseHeaders headers) throws Exception {
133+
builder.accumulate(headers);
134+
return STATE.CONTINUE;
135+
}
136+
137+
public Response onCompleted() throws Exception {
138+
return builder.build();
139+
}
140+
141+
}
142+
143+
Response response = client.prepareGet("http://sonatype.com").execute(asyncHandler).get();
144+
+-----+
145+
146+
One thing to consider when creating a <<<Response>>> object is the size of the response body. By default,
147+
a <<<Response>>> object will accumulate all response's bytes in memory, and that could potentially create an out of
148+
memory error. If you are planning to use the API for downloading large files, it is not recommended to accumulate
149+
bytes in memory and instead flush the bytes on disk as soon as they are available. Note that you can still use the
150+
<<<Response>>> object, except you don't accumulate the response's bytes as demonstrated below:
151+
152+
+-----+
153+
MyAsyncHandler<Response> asyncHandler = new MyAsyncHanfler<Response>() {
154+
private final Response.ResponseBuilder builder = new Response.ResponseBuilder();
155+
156+
public STATE onBodyPartReceived(final HttpResponseBodyPart content) throws Exception {
157+
content.write(myOutputStream);
158+
return STATE.CONTINUE;
159+
}
160+
161+
public STATE onStatusReceived(final HttpResponseStatus status) throws Exception {
162+
builder.accumulate(status); return STATE.CONTINUE;
163+
}
164+
165+
public STATE onHeadersReceived(final HttpResponseHeaders headers) throws Exception {
166+
builder.accumulate(headers);
167+
return STATE.CONTINUE;
168+
}
169+
170+
public Response onCompleted() throws Exception {
171+
return builder.build();
172+
}
173+
174+
}
175+
176+
Response response = client.prepareGet("http://sonatype.com").execute(asyncHandler).get();
177+
+-----+
178+
179+
Note that in the above scenario invoking <<<Response.getResponseBodyAsStream()>>> or <<<getResponseBody()>>> will
180+
return an <<<IllegalStateException>>> because the body wasn't accumulated by the <<<Response>>> object.

0 commit comments

Comments
 (0)