Search code examples
javapostjerseymuleform-parameter

How do I sneak my message body past Jersey, perhaps using Mule


So I'm using an older version of Mule (3.3.1) and Jersey (1.6) -very new to both and unable to upgrade- and having a similar problem to "null in FormParam with “charset=UTF-8” in Jersey 2.0" in that HTML form data being @POSTed is always null but using (to force a non UTF-8 charset) makes no difference, my @FormParams are still null.

<flow name="repo" doc:name="Repository application">
    <inbound-endpoint ref="RepositoryInternalEndpoint">
        <not-filter>
            <wildcard-filter pattern="/favicon.ico"/>
        </not-filter>
    </inbound-endpoint>

    <!-- All seems fine at this point -->
    <!--<custom-interceptor class="TestInterceptor"/>-->

    <!-- Inside the RepositoryService class, @FormParam args are null -->
    <jersey:resources doc:name="Repository Service Component">
        <component>
            <spring-object bean="repositoryService"/>
        </component>
    </jersey:resources>
</flow>

It seems as though Jersey is just eating my request body. Given that if I insert the TestInterceptor (in comments above) which simply outputs message properties including the message body and @FromParams, all the expected data is there. Is there a way to stop Jersey doing this or get the data beforehand?

The expected @FormParam arguments are all String as such...

@POST
@Path("/my/url")
@Consumes(MediaType.APPLICATION_FORM_URLENCODED)
@Produces(MediaType.TEXT_HTML)
public Response myMethod(@FormParam("o_serviceId") String serviceId){}

The command used was

curl -X POST -H "content-type: application/x-www-form-urlencoded" -d "o_serviceId=12345y" localhost:8889/my/url

Solution

  • I believe you are getting bitten by this long standing issue: https://www.mulesoft.org/jira/browse/MULE-5687

    When comparing Mule message payloads between the HTTP and the Jetty connectors, I noticed that it's actually an empty String for application/x-www-form-urlencoded requests for the latter while it contains the actual body for the former.

    Indeed if I add this before jersey:resources, everything works fine:

    <set-payload
        value="#[org.mule.util.StringUtils.join(message.inboundProperties['request.parameters'].entrySet(),'&amp;')]" />
    

    This basically rebuilds the message payload out of the request parameters. It's a quick and dirty fix: it does not re-encode the parameters properly and it assumes that Map.Entry.toString() always returns key=value. But it's easy to improve with a proper Map to URL-encoded string transformation...