Configuring a resource to receive multipart/form-data parts from an HTML form submission in JAX-RS 2.0
HTML forms that transmit file data must be configured with the POST method and the "multipart/form-data" action. The resource method executing in IBM's implementation of the Java™ API for RESTful Web Services (JAX-RS) specification can receive this data in one of the two ways.
About this task
The most recent documentation for multipart/form-data parts in JAX-RS 2.0 and later is available on the Open Liberty website.
In Jakarta Restful Web Services 3.0 and earlier, support for sending and receiving
multipart/form-data parts was provided by the Liberty-specific IAttachment
and
IMultipartBody
APIs, which are deprecated in version 3.1, which is included in
Liberty 23.0.0.3. In this version and later, this support is provided by the
EntityPart
API that is defined in the RESTful Web Services specification. For more
information, see section 3.5.2 of the Jakarta Restful Web Services
specification.
and
<form action="http://www.example.com/" method="POST" enctype="multipart/form-data">
<input type="text" name="fileid" />
<br />
<input type="text" name="description" />
<br />
<input type="file" name="thefile" />
<br />
<input type="submit" name="submit" value="submit"/>
</form>
You can implement your JAX-RS resource method to receive the data in parts, so
you can process these parts yourself, if needed.Procedure
@POST
@Consumes("multipart/form-data")
@Produces("multipart/form-data")
public Response postFormData(IMultipartBody multipartBody) {
List <IAttachment> attachments = multipartBody.getAllAttachments();
String formElementValue = null;
InputStream stream = null;
for (Iterator<IAttachment> it = attachments.iterator(); it.hasNext();) {
IAttachment attachment = it.next();
if (attachment == null) {
continue;
}
DataHandler dataHandler = attachment.getDataHandler();
stream = dataHandler.getInputStream();
MultivaluedMap<String, String> map = attachment.getHeaders();
String fileName = null;
String formElementName = null;
String[] contentDisposition = map.getFirst("Content-Disposition").split(";");
for (String tempName : contentDisposition) {
String[] names = tempName.split("=");
formElementName = names[1].trim().replaceAll("\"", "");
if ((tempName.trim().startsWith("filename"))) {
fileName = formElementName;
}
}
if (fileName == null) {
StringBuffer sb = new StringBuffer();
BufferedReader br = new BufferedReader(new InputStreamReader(stream));
String line = null;
try {
while ((line = br.readLine()) != null) {
sb.append(line);
}
} catch (IOException e) {
e.printStackTrace();
} finally {
if (br != null) {
try {
br.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
formElementValue = sb.toString();
System.out.println(formElementName + ":" + formElementValue);
} else {
//handle the file as you want
File tempFile = new File(fileName);
...
}
}
if (stream != null) {
stream.close();
}
return Response.ok("test").build();
}
Or
@POST
@Consumes("multipart/form-data")
@Produces("multipart/form-data")
public Response postFormData(IMultipartBody multipartBody) {
List <IAttachment> attachments = multipartBody.getAllAttachments();
String formElementValue = null;
InputStream stream = null;
for (Iterator<IAttachment> it = attachments.iterator(); it.hasNext();) {
IAttachment attachment = it.next();
if (attachment == null) {
continue;
}
DataHandler dataHandler = attachment.getDataHandler();
stream = dataHandler.getInputStream();
MultivaluedMap<String, String> map = attachment.getHeaders();
String fileName = null;
String formElementName = null;
String[] contentDisposition = map.getFirst("Content-Disposition").split(";");
for (String tempName : contentDisposition) {
String[] names = tempName.split("=");
formElementName = names[1].trim().replaceAll("\"", "");
if ((tempName.trim().startsWith("filename"))) {
fileName = formElementName;
}
}
if (fileName == null) {
StringBuffer sb = new StringBuffer();
BufferedReader br = new BufferedReader(new InputStreamReader(stream));
String line = null;
try {
while ((line = br.readLine()) != null) {
sb.append(line);
}
} catch (IOException e) {
e.printStackTrace();
} finally {
if (br != null) {
try {
br.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
formElementValue = sb.toString();
System.out.println(formElementName + ":" + formElementValue);
} else {
//handle the file as you want
File tempFile = new File(fileName);
...
}
}
if (stream != null) {
stream.close();
}
return Response.ok("test").build();
}
The
originator of the form POST submission can generate a Content-Transfer-Encoding header for one or
more parts of the multipart message. The IBM JAX-RS implementation attempts to auto-decode the
payload of the part according to this header when the header is of base64
or
quoted-printable
encoding type.Results
Your resource method will receive and echo data from an HTTP POST with multipart/form-data Content-Type. IBM's JAX-RS implementation will split and auto-decode the parts for you, allowing the application code in the resource method to process the form data.