...
We will use the commons-fileupload lib to have a multipart-formdata parser out-of-box.
The below code shows how it is checked if the request is a multipart-formdata request and the data is extracted.
Finally we create a message exchange and fill it with a dummy content and the uploaded file in the attachment.
Code Block |
---|
| java | java |
---|
title | createExchange method with additional comments |
---|
| java |
---|
|
public MessageExchange createExchange(HttpServletRequest request, ComponentContext context) throws Exception
{
// create a message exchange with the set default MEP
MessageExchange me = context.getDeliveryChannel().createExchangeFactory().createExchange(getDefaultMep());
// Check if we have got a file upload request (multipart content)
boolean isMultipart = ServletFileUpload.isMultipartContent(request);
if (isMultipart)
{
// create the "in" message
NormalizedMessage in = me.createMessage();
// set a dummy content, otherwise the NMR will throw errors - null content not allowed
in.setContent(new StringSource("<payload/>"));
// Parse the request with the FileUploadServlet
List items = upload.parseRequest(request);
// Process the uploaded items
Iterator iter = items.iterator();
while (iter.hasNext())
{
FileItem item = (FileItem)iter.next();
if (item.isFormField())
{
// this item is a formular field
processFormField(item, in);
}
else
{
// this item is a file content item
processUploadedFile(item, in);
}
}
// set this in message as the "in" message of the message exchange
me.setMessage(in, "in");
}
else
{
throw new Exception("Request is not a valid multipart message");
}
// finally return the ready exchange to be sent
return me;
}
|
...
In this method we just take the first attachment in the message exchange and write it to a temporary file.
Afterwards the response header is set and the file is posted as stream into the response's output stream.
Notice that we make use of the sendError method of our super class to handle exceptions.
Code Block |
java |
---|
| java |
---|
title | sendOut method with additional comments |
---|
| java |
---|
|
public void sendOut(MessageExchange exchange, NormalizedMessage outMsg, HttpServletRequest request,
HttpServletResponse response) throws Exception
{
// define a DataHandler (see Java Activation Framework)
DataHandler dh = null;
// if the out message received has no attachments, then we send an error to the client
if (outMsg.getAttachmentNames().isEmpty())
{
// use the super class method sendError to send an error to the client
sendError(exchange, new Exception("Invalid answer from handler."), request, response);
// and return
return;
}
// get all attachment names from the out message
Set set = outMsg.getAttachmentNames();
Iterator iterator = set.iterator();
String key = null;
if (iterator.hasNext())
{
// we are now only interested in the first attachment
key = iterator.next().toString(); // this resolves the key which is also the filename
dh = outMsg.getAttachment(key); // this will resolve the data handler (file content)
}
else
{
sendError(exchange, new Exception("Invalid answer from handler."), request, response);
return;
}
if (dh == null)
{
sendError(exchange, new Exception("Invalid answer from handler."), request, response);
return;
}
// create a temporary file
File f = File.createTempFile("tmp_", key);
// open an output stream to this file
FileOutputStream fos = new FileOutputStream(f);
// now we use the FileUtil's copyInputStream method to copy the content of the data
// handlers data source into the output stream
FileUtil.copyInputStream(dh.getDataSource().getInputStream(), fos);
// and close the output stream afterwards
fos.close();
// now create a file data source with the temporary file
FileDataSource fds = new FileDataSource(f);
// create a stream datasource with the input stream of the file data source, the
// content type is provided by a method of the FileDataSource
StreamDataSource sds = new StreamDataSource(fds.getInputStream(), fds.getContentType());
// then a new datahandler is created with the stream datasource
DataHandler dhsds = new DataHandler(sds);
// tells the response object to open a popup in the clients browser with the given
// filename (stored in key)
response.setHeader("content-disposition", "attachment; filename=\"" + key + "\"");
// set the content type to what the FileDataSource determined automatically
response.setContentType(fds.getContentType());
// also set the length of the content
response.setContentLength((int)f.length());
try
{
// now get the output stream of the servlet to send data to the clients browser
ServletOutputStream sos = response.getOutputStream();
// use the writeTo method of the data handler to easy to output of the data
// into the servlets output stream
dhsds.writeTo(sos);
// finally set the status of the response to OK
response.setStatus(HttpServletResponse.SC_OK);
}
catch (Exception e)
{
logger.log(Level.WARNING, "Exception occurred" + e.getMessage(), e);
}
// afterwards clean up the temporary file
f.deleteOnExit();
}
|
The finished class
Code Block |
java |
---|
| java |
---|
title | HTTPMarshaler.java |
---|
borderStyle | solid |
---|
| java |
---|
|
package org.apache.servicemix.jbi;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.Iterator;
import java.util.List;
import java.util.Set;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.activation.DataHandler;
import javax.activation.DataSource;
import javax.activation.FileDataSource;
import javax.jbi.component.ComponentContext;
import javax.jbi.messaging.MessageExchange;
import javax.jbi.messaging.MessagingException;
import javax.jbi.messaging.NormalizedMessage;
import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.apache.commons.fileupload.FileItem;
import org.apache.commons.fileupload.disk.DiskFileItemFactory;
import org.apache.commons.fileupload.servlet.ServletFileUpload;
import org.apache.servicemix.http.endpoints.DefaultHttpConsumerMarshaler;
import org.apache.servicemix.jbi.jaxp.StringSource;
import org.apache.servicemix.jbi.messaging.MessageExchangeSupport;
import org.apache.servicemix.jbi.util.ByteArrayDataSource;
import org.apache.servicemix.jbi.util.FileUtil;
import org.apache.servicemix.jbi.util.StreamDataSource;
public class HTTPMarshaler extends DefaultHttpConsumerMarshaler
{
private static final Logger logger = Logger.getLogger(HTTPMarshaler.class.getName());
private static final int MAX_MEM_SIZE = 10 * 1024 * 1024;
private static final File TEMP_FOLDER = new File(System.getProperty("java.io.tmpdir"));
private static final long MAX_UPLOAD_SIZE = 1024 * 1024 * 100;
private DiskFileItemFactory factory;
private ServletFileUpload upload;
/**
* constructor
*/
public HTTPMarshaler()
{
super(MessageExchangeSupport.IN_OUT);
// Create a factory for disk-based file items
factory = new DiskFileItemFactory();
// Set factory constraints
factory.setSizeThreshold(MAX_MEM_SIZE);
factory.setRepository(TEMP_FOLDER);
// Create a new file upload handler
upload = new ServletFileUpload(factory);
// Set overall request size constraint
upload.setSizeMax(MAX_UPLOAD_SIZE);
}
public MessageExchange createExchange(HttpServletRequest request, ComponentContext context) throws Exception
{
MessageExchange me = context.getDeliveryChannel().createExchangeFactory().createExchange(getDefaultMep());
// Check that we have a file upload request
boolean isMultipart = ServletFileUpload.isMultipartContent(request);
if (isMultipart)
{
NormalizedMessage in = me.createMessage();
in.setContent(new StringSource("<payload/>"));
// Parse the request
List items = upload.parseRequest(request);
// Process the uploaded items
Iterator iter = items.iterator();
while (iter.hasNext())
{
FileItem item = (FileItem)iter.next();
if (item.isFormField())
{
processFormField(item, in);
}
else
{
processUploadedFile(item, in);
}
}
me.setMessage(in, "in");
}
else
{
throw new Exception("Request is not a valid multipart message");
}
return me;
}
/**
* processes form fields
*
* @param item the field
* @param msg the in message
*/
private void processFormField(FileItem item, NormalizedMessage msg)
{
String name = item.getFieldName();
String value = item.getString();
msg.setProperty(name, value);
}
/**
* processes file items
*
* @param item the item
* @param msg the in message
*/
private void processUploadedFile(FileItem item, NormalizedMessage msg)
{
String fieldName = item.getFieldName();
String fileName = item.getName();
String contentType = item.getContentType();
boolean isInMemory = item.isInMemory();
long sizeInBytes = item.getSize();
DataHandler dh = null;
if (isInMemory)
{
dh = new DataHandler(new ByteArrayDataSource(item.get(), item.getContentType()));
}
else
{
try
{
dh = new DataHandler(new StreamDataSource(item.getInputStream(), item.getContentType()));
}
catch (IOException ioex)
{
dh = new DataHandler(new ByteArrayDataSource(item.get(), item.getContentType()));
}
}
try
{
msg.addAttachment(fileName, dh);
}
catch (MessagingException e)
{
e.printStackTrace();
}
}
public void sendOut(MessageExchange exchange, NormalizedMessage outMsg, HttpServletRequest request,
HttpServletResponse response) throws Exception
{
DataHandler dh = null;
if (outMsg.getAttachmentNames().isEmpty())
{
sendError(exchange, new Exception("Invalid answer from handler."), request, response);
return;
}
Set set = outMsg.getAttachmentNames();
Iterator iterator = set.iterator();
String key = null;
if (iterator.hasNext())
{
key = iterator.next().toString();
dh = outMsg.getAttachment(key);
}
else
{
sendError(exchange, new Exception("Invalid answer from handler."), request, response);
return;
}
if (dh == null)
{
sendError(exchange, new Exception("Invalid answer from handler."), request, response);
return;
}
File f = File.createTempFile("tmp_", key);
FileOutputStream fos = new FileOutputStream(f);
FileUtil.copyInputStream(dh.getDataSource().getInputStream(), fos);
fos.close();
FileDataSource fds = new FileDataSource(f);
StreamDataSource sds = new StreamDataSource(fds.getInputStream(), fds.getContentType());
DataHandler dhsds = new DataHandler(sds);
response.setHeader("content-disposition", "attachment; filename=\"" + key + "\"");
response.setContentType(fds.getContentType());
response.setContentLength((int)f.length());
try
{
ServletOutputStream sos = response.getOutputStream();
dhsds.writeTo(sos);
response.setStatus(HttpServletResponse.SC_OK);
}
catch (Exception e)
{
logger.log(Level.WARNING, "Exception occurred" + e.getMessage(), e);
}
f.deleteOnExit();
}
}
|
...