我如何偷偷通过 Jersey 发送消息正文,也许使用 Mule

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

所以我使用的是旧版本的 Mule (3.3.1) 和 Jersey (1.6) - 两者都很新并且无法升级 - 和 "null in FormParam with “charset=UTF-8” in Jersey 2.0" in that HTML form data being @POSTed is always null but using 有类似的问题(强制使用非 UTF-8 字符集)没有区别,我的 @FormParam 仍然是 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>

好像 Jersey 正在吃掉我的请求体。鉴于如果我插入 TestInterceptor(在上面的评论中),它只输出消息属性,包括消息正文和 @FromParams,那么所有预期的数据都在那里。有没有办法阻止 Jersey 这样做或事先获取数据?

预期的 @FormParam 个参数都是 String 这样的...

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

使用的 命令是

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

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...