You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@hc.apache.org by Apache Wiki <wi...@apache.org> on 2006/12/16 21:12:23 UTC

[Jakarta-httpclient Wiki] Update of "FrequentlyAskedApplicationDesignQuestions" by RolandWeber

Dear Wiki user,

You have subscribed to a wiki page or wiki category on "Jakarta-httpclient Wiki" for change notification.

The following page has been changed by RolandWeber:
http://wiki.apache.org/jakarta-httpclient/FrequentlyAskedApplicationDesignQuestions

New page:
#pragma section-numbers 2

= Application Design FAQ =

This document addresses questions about application design which
have been raised repeatedly on the HttpClient and HttpComponents mailing lists.
As it addresses design issues rather than API or other HttpClient or
HttpComponents specific problems, much of the information presented
is equally applicable for HttpURLConnection or non-Java APIs.

If you are just getting your feet wet and want to understand the basics
of client HTTP programming rather than read about application design alternatives,
check out our [wiki:Self:ForAbsoluteBeginners primer].

----
[[TableOfContents]]
----


== Sending Parameters and Uploading Files  ==

A question that is asked on a regular basis is:

 ''How do I upload a file along with some parameters?''

This section presents different ways to upload parameters, files, and both.
It assumes that you are implementing both a client application and
a server application to which the client application connects.
The client application might be a Java program using HttpClient,
while the server application is assumed to be a
[http://java.sun.com/products/servlet/2.3/javadoc/javax/servlet/http/HttpServlet.html Servlet].

Parameters are name/value pairs, where both name and value are strings.
Names should always be in US-ASCII, values may use other character
encodings, depending on the technique used for sending the parameters.
Files or rather file parameters are name/value pairs, where the name is
a string and the value is binary data read from a file. Binary values
from other sources can be handled similar to files from a design perspective,
though the details of the API will vary.


=== GET with Query ===

The simplest way to transfer parameters to the server is the
query string of the URL. That's the part after the question mark,
for example in:

 http:''''''//my.server.name/my/servlet'''?param1=value1&param2=value2'''

Query strings can be used with any HTTP method, but they are most
frequently used with the GET method. A query string is also the
only way to send parameters with a GET method.
(Unless your application encodes parameters into the URL path.)

Query strings works only for string values. Special characters
like = & % and the space character need to be escaped as
a % character followed by two hex digits specifying
the ASCII value of the character.
The encoding of special characters is automatically handled for example
by the [http://java.sun.com/j2se/1.5.0/docs/api/java/net/URI.html#URI(java.lang.String,%20java.lang.String,%20java.lang.String,%20int,%20java.lang.String,%20java.lang.String,%20java.lang.String) java.net.URI]
and [http://jakarta.apache.org/commons/httpclient/apidocs/org/apache/commons/httpclient/URI.html#setRawQuery(char%5b%5d) org.apache.commons.httpclient.URI] classes.
URLs are confined to using ASCII characters exclusively. Only ASCII values
can reliably be transferred in a query string. However, some browsers
handle non-ASCII input in HTML forms by encoding those characters, for
example in UTF-8, and escaping the non-ASCII bytes as %xx sequences.
It is strongly discouraged to send non-ASCII values in the query string.

On the server, name/value pairs sent in a query string are available
as parameters of the [http://java.sun.com/products/servlet/2.3/javadoc/javax/servlet/ServletRequest.html#getParameter(java.lang.String) ServletRequest].
%xx escape sequences are automatically decoded by the Servlet API.
If non-ASCII values are sent in the query string, the outcome depends
on the implementation of the Servlet API and possibly also on
configuration parameters, such as the JVM default character set.
That's why it is strongly discouraged to send non-ASCII values
in the query string.


=== POST with URL-encoded Form Data ===

Unlike the GET method, a POST method has a message body or entity
which can hold any kind of binary or non-binary data.
A simple way to send parameters with string values to the server
is to put the query string into the message body instead of the URL.
This avoids URL length restrictions, problems with parameters being
logged where they shouldn't, and it also allows for non-ASCII characters
in the values. While a URL is confined to ASCII characters, the
message body is not. The character set can be specified in a header field.
The encoding of special characters is automatically handled by
HttpClient's [http://jakarta.apache.org/commons/httpclient/apidocs/org/apache/commons/httpclient/methods/PostMethod.html PostMethod].

On the server, name/value pairs sent in a message body with
content type "application/x-www-form-urlencoded" are available
as parameters of the [http://java.sun.com/products/servlet/2.3/javadoc/javax/servlet/ServletRequest.html#getParameter(java.lang.String) ServletRequest].
If there are parameters in both the message body and the query string,
all of them are available in the !ServletRequest.


=== POST with Multipart Form Data ===

In order to upload binary data such as files, the data can be encoded as
multipart [http://www.ietf.org/rfc/rfc1521.txt MIME].
That's the same format which is used for sending email attachments.
HTML forms for uploading files have to specify the content type
"multipart/form-data" so the browser knows that the multipart MIME encoding
must be applied. That content type is also sent to the server.
HttpClient provides the [http://jakarta.apache.org/commons/httpclient/apidocs/org/apache/commons/httpclient/methods/multipart/MultipartRequestEntity.html MultipartRequestEntity]
class to perform multipart MIME encoding.

On the server, parameters sent as multipart MIME are ''not'' available
as parameters of the 
[http://java.sun.com/products/servlet/2.3/javadoc/javax/servlet/ServletRequest.html#getParameter(java.lang.String) ServletRequest].
The servlet has to read and interpret the message body explicitly.
There are libraries for parsing multipart MIME data, for example
[http://jakarta.apache.org/commons/fileupload/ Commons FileUpload].
It should also be possible to parse multipart/form-data using the
[http://java.sun.com/products/javamail/FAQ.html#attach JavaMail API].
If there are parameters in both the message body and the query string,
only those from the query string are available in the !ServletRequest.


=== POST with Query and Data ===

In the special case that you need to upload only parameters with
ASCII string values and a single file, there is another option.
You can send the parameters in a query string and the file contents
as the message body. This does not require special encoding or
decoding of the binary data.
This kind of request can not be generated by an HTML form.
[[BR]]
With this approach, the file is not sent as a name/value pair.
Only the value, that is the file contents, will be transferred.
The servlet has to know what to do with the file based only on
the information in the URL (and HTTP headers). The information in
the URL can come from the query string (?name=!MyImage.png),
from the URL path (/my/servlet/save), or both.
[[BR]]
You should specify a content type that indicates the type of data
you are sending in the message body, such as "application/octet-stream"
or "image/png" or whatever else is appropriate for the file you are uploading.
If you are uploading a text file, you should also specify the
character set as part of the content type.

On the server, the parameters sent in the query string are available
as parameters of the 
[http://java.sun.com/products/servlet/2.3/javadoc/javax/servlet/ServletRequest.html#getParameter(java.lang.String) ServletRequest].
The file contents is available as from the !ServletRequest as either
[http://java.sun.com/products/servlet/2.3/javadoc/javax/servlet/ServletRequest.html#getInputStream() binary]
or
[http://java.sun.com/products/servlet/2.3/javadoc/javax/servlet/ServletRequest.html#getReader() character]
data.


=== Further Reading ===

[http://java.sun.com/j2se/1.5.0/docs/api/java/net/HttpURLConnection.html Java Standard Edition 5.0, HttpURLConnection]

[http://www.iana.org/assignments/media-types/ IANA: Registered MIME Media Types]

[http://java.sun.com/products/servlet/docs.html Sun: Java Servlet Technology Documentation]

[http://java.sun.com/products/servlet/2.3/javadoc/ Servlet API 2.3]

[http://java.sun.com/javaee/5/docs/api/javax/servlet/package-summary.html Java Enterprise Edition 5.0, Servlet API 2.4]

[http://java.sun.com/products/javamail/reference/index.html JavaMail]

[http://java.sun.com/javaee/5/docs/api/javax/mail/package-summary.html Java Enterprise Edition 5.0, JavaMail API]

---------------------------------------------------------------------
To unsubscribe, e-mail: httpcomponents-dev-unsubscribe@jakarta.apache.org
For additional commands, e-mail: httpcomponents-dev-help@jakarta.apache.org