Skip to content
Advertisement

Get key-value pairs from multipart/form-data HTTP POST request in Camel

I have an endpoint setup using Apache Camel to receive a multipart/form-data HTTP request. Essentially I am trying to submit a data file and a configuration file for processing. The request is as follows (generated by Postman):

POST /upload HTTP/1.1
Host: localhost:8900
Content-Length: 363
Content-Type: multipart/form-data; boundary=----WebKitFormBoundary7MA4YWxkTrZu0gW

----WebKitFormBoundary7MA4YWxkTrZu0gW
Content-Disposition: form-data; name="data"; filename="data-file.json"
Content-Type: application/json

(data)
----WebKitFormBoundary7MA4YWxkTrZu0gW
Content-Disposition: form-data; name="config"; filename="config-file.json"
Content-Type: application/json

(data)
----WebKitFormBoundary7MA4YWxkTrZu0gW

My route is set up like so:

@Component
public class FileReceiverRoute extends RouteBuilder {

    @Override
    public void configure() throws Exception {

        rest()
                .post("/upload")
                .consumes(MediaType.MULTIPART_FORM_DATA_VALUE)
                .bindingMode(RestBindingMode.off)
                .route().routeId("upload-route")
                .unmarshal().mimeMultipart()
                .setHeader(Exchange.FILE_NAME, () -> UUID.randomUUID().toString())
                .to("file:{{temp.input.files.dir}}")
                .process(configFileProcessor)
                // on to further processing
    }
}

And my config file processor:

@Component
public class ConfigFileProcessor implements Processor {

    @Override
    public void process(Exchange exchange) throws Exception {
        Message message = exchange.getIn();
        AttachmentMessage attachmentMessage = exchange.getMessage(AttachmentMessage.class);
        Map<String, Attachment> attachmentObjects = attachmentMessage.getAttachmentObjects();

        // this fails - the key is instead the file name "config-file.json"
        Attachment configAttachment = attachmentObjects.get("config");
    }
}

I want to be able to retrieve the key-value pairs from the form-data and process the data and config files accordingly. Instead I get the following behaviour:

  • The first value in the form (in this case data-file.json) is parsed into the Camel message body, and the key seems to be discarded. The rest of the entries are parsed into an AttachmentMessage. This behaviour is documented here https://stackoverflow.com/a/67566273/11248602
  • The keys in the AttachmentMessage are not the original keys from the form-data request, but the filenames (e.g. config-file.json)

Is there any way to parse this request into a map or similar structure so that all the original keys and values can be accessed?

Advertisement

Answer

For the sake of clarity, as the proposed solution here above seems to work, a bit more explanations (although it is more a workaround than a solution):

Starting from:

Map<String, Attachment> attachmentObjects = attachmentMessage.getAttachmentObjects();

It is possible to browse all map entries, and for each found Attachment object, examine the attachment headers using getHeaderNames(), among other the ‘Content-Disposition’ one:

Content-Disposition: form-data; name="data"; filename="data-file.json"

which can finally be parsed to grab the form name (‘data’ in this example).

Not straightforward true, but this apparently works…

User contributions licensed under: CC BY-SA
7 People found this is helpful
Advertisement