multipart form data
TRANSCRIPT
![Page 1: Multipart Form Data](https://reader036.vdocument.in/reader036/viewer/2022082511/547f8a62b4af9fbe158b5b50/html5/thumbnails/1.jpg)
http://stackoverflow.com/questions/96360/writing-post-data-from-one-java-servlet-to-another
Writing post data from one java servlet to another
up vot
e5down
votefavorite
1share
[g+]share [fb]share
[tw]
I am trying to write a servlet that will send a XML file (xml formatted string) to another servlet via a POST. (Non essential xml generating code replaced with "Hello there")
StringBuilder sb= new StringBuilder(); sb.append("Hello there");
URL url = new URL("theservlet's URL"); HttpURLConnection connection = (HttpURLConnection)url.openConnection(); connection.setRequestMethod("POST"); connection.setRequestProperty("Content-Length", "" + sb.length());
OutputStreamWriter outputWriter = new OutputStreamWriter(connection.getOutputStream()); outputWriter.write(sb.toString()); outputWriter.flush(); outputWriter.close();
This is causing a server error, and the second servlet is never invoked.
java servlets
link|improve this question asked Sep 18 '08 at 20:06
denny8771816
75% accept rate
feedback
5 Answers
![Page 2: Multipart Form Data](https://reader036.vdocument.in/reader036/viewer/2022082511/547f8a62b4af9fbe158b5b50/html5/thumbnails/2.jpg)
active oldest votes
up vot
e11down
voteaccepted
This kind of thing is much easier using a library like HttpClient. There's even a post XML code example:PostMethod post = new PostMethod(url);RequestEntity entity = new FileRequestEntity(inputFile, "text/xml; charset=ISO-8859-1");post.setRequestEntity(entity);HttpClient httpclient = new HttpClient();int result = httpclient.executeMethod(post);
link|improve this answer answered Sep 18 '08 at 20:13
Peter Hilton7,0651850
feedback
up vot
e7down
vote
I recommend using Apache HTTPClient instead, because it's a nicer API.But to solve this current problem: try calling connection.setDoOutput(true); after you open the connection.StringBuilder sb= new StringBuilder();sb.append("Hello there");
URL url = new URL("theservlet's URL");HttpURLConnection connection = (HttpURLConnection)url.openConnection(); connection.setDoOutput(true);connection.setRequestMethod("POST");connection.setRequestProperty("Content-Length", "" + sb.length());
OutputStreamWriter outputWriter = new OutputStreamWriter(connection.getOutputStream());outputWriter.write(sb.toString());outputWriter.flush();outputWriter.close();
link|improve this answer edited Sep 18 '08 at 20:17 answered Sep 18 '08 at 20:12
![Page 3: Multipart Form Data](https://reader036.vdocument.in/reader036/viewer/2022082511/547f8a62b4af9fbe158b5b50/html5/thumbnails/3.jpg)
Sietse1,87821436
feedbackup vot
e2down
vote
Don't forget to use:
connection.setDoOutput( true)
if you intend on sending output.
link|improve this answer answered Sep 18 '08 at 20:10
Craig B.16218
feedbackup vot
e1down
vote
The contents of an HTTP post upload stream and the mechanics of it don't seem to be what you are expecting them to be. You cannot just write a file as the post content, because POST has very specific RFC standards on how the data included in a POST request is supposed to be sent. It is not just the formatted of the content itself, but it is also the mechanic of how it is "written" to the outputstream. Alot of the time POST is now written in chunks. If you look at the source code of Apache's HTTPClient you will see how it writes the chunks.
There are quirks with the content length as result, because the content length is increased by a small number identifying the chunk and a random small sequence of characters that delimits each chunk as it is written over the stream. Look at some of the other methods described in newer Java versions of the HTTPURLConnection.
http://java.sun.com/javase/6/docs/api/java/net/HttpURLConnection.html#setChunkedStreamingMode(int)If you don't know what you are doing and don't want to learn it, dealing with adding a dependency like Apache HTTPClient really does end up being much easier because it abstracts all the complexity and just works.
link|improve this answer answered Sep 19 '08 at 21:18
Josh2,3761819
Was this post useful to you?
![Page 4: Multipart Form Data](https://reader036.vdocument.in/reader036/viewer/2022082511/547f8a62b4af9fbe158b5b50/html5/thumbnails/4.jpg)
http://www.devx.com/java/Article/17679/1954
http://www.devx.com
Printed from http://www.devx.com/java/Article/17679/1954
Send Form Data from Java: A Painless Solution
Sending multipart/form data from Java is a painful process that bogs developers down in
protocol details. This article provides a simple, real-world solution that makes sending
POST requests as simple as sending GET requests, even when sending multiple files of
varying type.
by Vlad Patryshev
ending simple GET requests from Java is extremely easy (be it an application or a servlet), but sending multipart
forms, like when you upload files, is painful. The former can be done in one method call that does all the underground
work. The latter requires explicitly creating an HTTP request, which may include generating multipart boundaries
while being careful with the exact amount and selection of newlines (e.g., println() would not always do the right
job).
This article provides a simple solution that will relieve the pain of sending form data (like POST requests) from Java in
most real-world scenarios. The intention is to make POST requests as simple as GET requests, even when sending
multiple files of varying type (archives, XML, HTML, plain text, etc.).
GET and POST Requests
The two main methods for sending form data to a Web server are GET and POST. This section demonstrates how
each method works in three scenarios. (Do not try to reproduce these at home. The URLs and e-mail addresses are
fake.)
Example 1. GET Request
The following form uses the GET method:
<form method="get" action="hi.iq/register.jsp">
Name: <input type="text" name="name" value="J.Doe">
![Page 5: Multipart Form Data](https://reader036.vdocument.in/reader036/viewer/2022082511/547f8a62b4af9fbe158b5b50/html5/thumbnails/5.jpg)
email: <input type="text" name="email" value="[email protected]">
<input type="submit">
</form>
It performs the same task as requesting the following URL: http:hi.iq/register.jsp?
name=J.Doe&email=abuse%40spamcop.com
If you were using Mozilla 5.0, the following would be the HTTP request sent to the server:
GET register.jsp?name=J.Doe&email=abuse%40spamcop.com HTTP/1.1
Host: hi.iq
User-Agent: Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.2) Gecko/20021126
Accept: text/xml,application/xml,application/xhtml+xml,text/html;q=0.9,text/
plain;q=0.8,
video/x-mng,image/png,image/jpeg,image/gif;q=0.2,text/css,*/*;q=0.1
Accept-Language: en-us, en;q=0.50
Accept-Encoding: gzip, deflate, compress;q=0.9
Accept-Charset: ISO-8859-1, utf-8;q=0.66, *;q=0.66Keep-Alive: 300Connection: keep-
alive
Example 2. POST Request
Now, let's replace 'GET' with 'POST' in the form HTML tag:
<form method="post" action="hi.iq/register.jsp">
Name: <input type="text" name="name" value="J.Doe">
email: <input type="text" name="email" value="[email protected]">
<input type="submit">
</form>
In this case, the HTTP request sent to the server looks like this:
POST register.jsp HTTP/1.1
Host: hi.iq
User-Agent: Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.2) Gecko/20021126
Accept: text/xml,application/xml,application/xhtml+xml,text/html;q=0.9,text/
plain;q=0.8,
video/x-mng,image/png,image/jpeg,image/gif;q=0.2,text/css,*/*;q=0.1
Accept-Language: en-us, en;q=0.50
Accept-Encoding: gzip, deflate, compress;q=0.9
![Page 6: Multipart Form Data](https://reader036.vdocument.in/reader036/viewer/2022082511/547f8a62b4af9fbe158b5b50/html5/thumbnails/6.jpg)
Accept-Charset: ISO-8859-1, utf-8;q=0.66, *;q=0.66
Keep-Alive: 300Connection: keep-alive
Content-Type: application/x-www-form-urlencoded
Content-Length: 36
name=J.Doe&email=abuse%40spamcop.com
Example 3. Multipart POST Request
If the form contains file upload, you have to add enctype="multipart/form-data" to the form tag. Otherwise, the file
won't be sent:
<form method="post" action="hi.iq/register.jsp" enctype="multipart/form-data">
Name: <input type="text" name="name" value="J.Doe">
email: <input type="text" name="email" value="[email protected]">
file: <input type="file" name="file-upload">
<input type="submit">
</form>
This form will produce the following HTTP request when sent from Mozilla 5:
POST register.jsp HTTP/1.1
Host: hi/iq
User-Agent: Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.2) Gecko/20021126
Accept: text/xml,application/xml,application/xhtml+xml,text/html;q=0.9,text/
plain;q=0.8,
video/x-mng,image/png,image/jpeg,image/gif;q=0.2,text/css,*/*;q=0.1
Accept-Language: en-us, en;q=0.50
Accept-Encoding: gzip, deflate, compress;q=0.9
Accept-Charset: ISO-8859-1, utf-8;q=0.66, *;q=0.66
Keep-Alive: 300
Connection: keep-alive
Content-Type: multipart/form-data; boundary=---------------------------29772313742745
Content-Length: 452
-----------------------------29772313742745
Content-Disposition: form-data; name="name"
J.Doe
-----------------------------29772313742745
Content-Disposition: form-data; name="email"
-----------------------------29772313742745
Content-Disposition: form-data; name="file-upload"; filename="test.txt"
Content-Type: text/plain
test data with some high ascii: ¿Como estás?
-----------------------------29772313742745--
![Page 7: Multipart Form Data](https://reader036.vdocument.in/reader036/viewer/2022082511/547f8a62b4af9fbe158b5b50/html5/thumbnails/7.jpg)
Send POST Requests from Java
Using the GET request from Java is very easy. You just create a URL with the request and then get an input stream:
InputStream is = new
URL("hi.iq/register?name=J.Doe&[email protected]").getInputStream();
In most cases, servers that process POST requests won't reject your GET request. Still, sometimes you'll have to
POST instead of GET, particularly when you upload a file. Wouldn't having a solution like the form from Example 2 be
nice? The corresponding Java request could look like this:
InputStream serverInput = ClientHttpRequest.post(
new java.net.URL("hi.iq/register"),
new Object[] {
"name", "J.Doe",
"email", "[email protected]",
"test.txt", new
File("C:\home\vp\tmp\test.txt")
});
Unfortunately, so far no such solution exists.
The Solution: ClientHttpRequest
If you search the Internet, you will find some partial or complicated solutions for using POST requests in Java. The
best commercial solution probably is JScape's HTTP(S) component. Its well-designed API covers everything
specified in HTTP (see RFC 2068). Other solutions are either too weird and complicated (see Ronald
Tschalär's HttpClient) or too literal to be useful (check out this post from JavaRanch).
Because of this lack of free, simple solutions, I had to develop my own (download the source code). It is of moderate
complexity and has an obvious interface that I hope is both simple and relatively universal. It can be instantiated from
a URL String, URL, or an already open URLConnection.
After a user creates an instance of ClientHttpRequest, the user can add request parameters and cookies. Cookies
are an important part of a request, especially with servlets that use cookies to keep track of sessions.
One can add parameters one by one, using the following:
setParameter(String name, String value);
setParameter(String name, File file);
setParameter(String parametername, String filename, InputStream fileinput)
Or set them all at once, using the following:
![Page 8: Multipart Form Data](https://reader036.vdocument.in/reader036/viewer/2022082511/547f8a62b4af9fbe158b5b50/html5/thumbnails/8.jpg)
setParameters(Map parameterMap)
or
setParameters(Object[] parameterArray).
The following method sets parameter as a string value or as a file depending on the argument type:
setParameter(String parametername, Object parameterdata).
This method works the same way for cookies. One can add cookies one by one, using the following:
setCookie(String name, String value)
Or set them all at once, using one of these:
setCookies(Map cookieMap)
setCookies(String[] cookieArray)
After the request is ready, the post() method posts the request and returns an input stream that will contain the
server's response, the same way as in URL.getInputStream(). For convenience, additional post methods are
available:
post(Map parameters);
post(Object[] parameters);
post(String[] cookies, Object[] parameters);
post(Map cookies, Map parameters).
The following group of static post methods does all of this in one fell swoop:
InputStream serverInput = post(URL url, Map parameters);
InputStream serverInput = post(URL url, Map cookies, Map parameters);
InputStream serverInput = post(URL url, String[] cookies, Object[] parameters);
InputStream serverInput = post(URL url, Object[] parameters).
All these methods let the user post a complicated form and receive an input stream in one expression, like the one in
Example 2 at the beginning of this article.
Answer to the Eternal Question
Now you know how an HTML form (GET or POST) gets passed to the server as an HTTP request and how you can
![Page 9: Multipart Form Data](https://reader036.vdocument.in/reader036/viewer/2022082511/547f8a62b4af9fbe158b5b50/html5/thumbnails/9.jpg)
reproduce this behavior in your Java program—without overloading it with protocol details. You could say this solution
answers the eternal question: How can one call a servlet or JSP from another servlet or JSP?
Vlad Patryshev is an R&D engineer at the Java Business Unit of Borland. He recently started
the myjavatools.com project. Contact him by e-mail.
DevX is a division of Internet.com. © Copyright 2010 Internet.com. All Rights Reserved. Legal Notices
http://www.discursive.com/books/cjcook/reference/http-webdav-sect-upload-multipart-post
11.9. uploading files with a multipart postTable of Contents
11.9.1. ProblemYou need to upload a file or a set of files with an HTTP multipart POST.
11.9.2. SolutionCreate a MultipartPostMethod and add File objects as parameters
using addParameter( ) and addPart( ). The MultipartPostMethod creates a
request with a Content-Typeheader of multipart/form-data, and each part is
separated by a boundary. The following example sends two files in an HTTP multipart POST:?
1
2
3
4
5
6
7
import org.apache.commons.httpclient.HttpClient;
import org.apache.commons.httpclient.HttpException;
import org.apache.commons.httpclient.methods.MultipartPostMethod;
import org.apache.commons.httpclient.methods.multipart.FilePart;
HttpClient client = new HttpClient( );
// Create POST method
String weblintURL = "http://ats.nist.gov/cgi-bin/cgi.tcl/echo.cgi";
![Page 10: Multipart Form Data](https://reader036.vdocument.in/reader036/viewer/2022082511/547f8a62b4af9fbe158b5b50/html5/thumbnails/10.jpg)
8
9
10
11
12
13
14
15
16
17
18
19
20
MultipartPostMethod method =
new MultipartPostMethod( weblintURL );
File file = new File( "data", "test.txt" );
File file2 = new File( "data", "sample.txt" );
method.addParameter("test.txt", file );
method.addPart( new FilePart( "sample.txt", file2, "text/plain",
"ISO-8859-1" ) );
// Execute and print response
client.executeMethod( method );
String response = method.getResponseBodyAsString( );
System.out.println( response );
method.releaseConnection( );
Two File objects are added to the MultipartPostMethod using two different methods.
The first method, addParameter( ), adds a File object and sets the file name
to test.txt. The second method, addPart(), adds a FilePart object to
the MultipartPostMethod. Both files are sent in the request separated by a part boundary,
and the script echoes the location and type of both files on the server:?
1
2
3
4
5
6
<h3>Form input</h3>
<pre>
sample.txt = /tmp/CGI14480.4 sample.txt {text/plain; charset=ISO-8859-1}
test.txt = /tmp/CGI14480.2 test.txt {application/octet-stream;
charset=ISO-8859-1}
</pre>
![Page 11: Multipart Form Data](https://reader036.vdocument.in/reader036/viewer/2022082511/547f8a62b4af9fbe158b5b50/html5/thumbnails/11.jpg)
11.9.3. DiscussionAdding a part as a FilePart object allows you to specify the Multipurpose Internet Main
Extensions (MIME) type and the character set of the part. In this example, thesample.txt file
is added with a text/plain MIME type and an ISO-8859-1 character set. If a File is
added to the method using addParameter( ) or setParameter( ), it is sent with the
default application/octet-stream type and the default ISO-8859-1 character set.
When HttpClient executes the MultipartPostMethod created in the previous example,
the following request is sent to the server. The Content-Type header
is multipart/form-data, and an arbitrary boundary is created to delineate multiple parts
being sent in the request:
POST /cgi-bin/cgi.tcl/echo.cgi HTTP/1.1
User-Agent: Jakarta Commons-HttpClient/3.0final
Host: ats.nist.gov
Content-Length: 498
Content-Type: multipart/form-data; boundary=----------------31415926535
8979323846
------------------314159265358979323846
Content-Disposition: form-data; name=test.txt; filename=test.txt
Content-Type: application/octet-stream; charset=ISO-8859-1
Content-Transfer-Encoding: binary
This is a test.
------------------314159265358979323846
Content-Disposition: form-data; name=sample.txt; filename=sample.txt
![Page 12: Multipart Form Data](https://reader036.vdocument.in/reader036/viewer/2022082511/547f8a62b4af9fbe158b5b50/html5/thumbnails/12.jpg)
Content-Type: text/plain; charset=ISO-8859-1
Content-Transfer-Encoding: binary
This is a sample
------------------314159265358979323846--
Each part contains a Content-Disposition header to name the part and a Content-
Typeheader to classify the part with a MIME type and character set.
11.9.4. See AlsoRFC 1867 (form-based file upload in HTML defines a multipart POST) can be found
athttp://www.zvon.org/tmRFC/RFC1867/Output/index.html. Each part is sent using MIME,
which is described in RFC 2045, Multipurpose Internet Mail Extensions (MIME) Part One:
Format of Internet Message Bodies (http://www.zvon.org/tmRFC/RF2045/Output/index.html).
http://hc.apache.org/httpclient-3.x/apidocs/index.html?org/apache/commons/httpclient/methods/multipart/MultipartRequestEntity.html
File f = new File("/path/fileToUpload.txt"); PostMethod filePost = new PostMethod("http://host/some_path"); Part[] parts = { new StringPart("param_name", "value"), new FilePart(f.getName(), f) }; filePost.setRequestEntity( new MultipartRequestEntity(parts, filePost.getParams()) ); HttpClient client = new HttpClient(); int status = client.executeMethod(filePost);