3
votes

I'm trying to send a form with a file and two inputs to an Mule inbound-endpoint. I've got a custom-processor, and a flow defined like that:

<custom-processor class="informa.app.classifier.transformers.MyfileUploadProcessor" name="fileuploadprocessor"></custom-processor>
<flow name="httpTest">
    <http:inbound-endpoint
                    address="http://tango.privada.informa:11002/services/fileupload"></http:inbound-endpoint>
    <processor ref="fileuploadprocessor"/>
</flow>

In the class MyfileUploadProcessor:

public class MyfileUploadProcessor implements MessageProcessor {

    @Override
    public MuleEvent process(MuleEvent event) throws MuleException {
        // TODO Auto-generated method stub
        String response = "success";

        MuleMessage mulemessage = event.getMessage();

        String countryCode = mulemessage.getInboundProperty("username");
        String sourceCode = mulemessage.getInboundProperty("password");
        InputStream input = (InputStream) mulemessage.getPayload();

...

And to test, a simple html:

<form action="http://tango.privada.informa:11002/services/fileupload" method="post"
enctype="multipart/form-data">
   <p>Country Code :<input type="text" name="username" /></p>
   <p>Source Code :<input type="text" name="password" /></p>
   <p>File :<input type="file" name="payload" /></p>
   <p><input type="submit" name="submit" value="submit" />
<input type="reset" name="reset" value="reset"></p>
</form>

</body>
</html>

The issue is I can't create a file from the payload of the mulemessage and I don't know how to get the value of the inputs in the form...what I'm doing wrong? any clues?

Thanks in advance

2

2 Answers

3
votes

You need to configure the HTTP connector to use the org.mule.transport.http.HttpMultipartMuleMessageFactory in order to handle multipart/form-data HTTP POSTs.

For this, add the following to your configuration:

<http:connector name="httpConnector">
    <service-overrides messageFactory="org.mule.transport.http.HttpMultipartMuleMessageFactory"/>
</http:connector>

With this in place, the payload form field will become the streaming payload of the Mule message and all the other fields values will be in inbound attachments (any part header will be in inbound headers).

1
votes

Great answer from David (a life saver for me !! cudos david) for what it is worth some extra items I didn't realize at first the httpConnector has to be used as http transport reference a full flow would be

<http:connector name="httpConnector" doc:name="HTTP\HTTPS">
        <service-overrides
            messageFactory="org.mule.transport.http.HttpMultipartMuleMessageFactory" />
    </http:connector>

<flow name="AttachmentTestFlow1" doc:name="AttachmentTestFlow1">        
    <http:inbound-endpoint connector-ref="httpConnector" doc:name="HTTP" exchange-pattern="request-response" host="localhost" port="8081"/>
    <component class="ProcessAttachment" doc:name="Java" />
</flow>

I was able to upload using jmeter adding two attachments, the first

  • has a paramter name = "payload" and mime-type="multipart/form-data"
  • the second has a user specificed name, e.g "attachment"

This can then be processed by a normal mule flow, or a component

public String process(@Payload String payload, @InboundAttachments("*") Map<String, DataHandler> headers  ) throws IOException{     
    InputStream in  = headers.get("attachment").getDataSource().getInputStream();