在mule 3.2中接收和发送multipart / form-data

时间:2012-08-09 10:50:28

标签: http mule

我在配置Mule 3.2时遇到问题,Mule 3.2基本上接收HTTP POST(multipart / form-data)并路由有效负载,然后通过HTTP POST(multipart / form-data)发送有效负载。如何在骡子中完成这种任务?

以下是我配置的部分内容

<flow name="UserBridgeFlow" doc:name="UserBridgeFlow">
    <inbound-endpoint address="http://${local.server}/${user.context}/" exchange-pattern="request-response" connector-ref="STD_HTTP_CONNECTOR" doc:name="User Endpoint"/>
    <echo-component doc:name="Echo"/>
    <transformer ref="RouteTransformer" doc:name="Transformer Reference"/>
    <response>
        <message-properties-transformer overwrite="true" doc:name="Message Properties">
            <add-message-property key="Access-Control-Allow-Origin" value="*"/>
        </message-properties-transformer>
    </response>
    <response>
        <echo-component doc:name="Echo"/>
    </response>
    <http:outbound-endpoint exchange-pattern="request-response" address="http://${user.server}/#[header:OUTBOUND:real.path]" doc:name="HTTP User"/>
    <default-exception-strategy>
        <processor-chain> 
            <logger level="INFO" doc:name="Logger"/> 
        </processor-chain>
    </default-exception-strategy>
</flow>

通过上述配置,我的二进制数据在到达另一个端点时总是被破坏,并且我在浏览器中遇到此错误(调用者端点)“未声明纯文本文档的字符编码。文档将如果文档包含来自US-ASCII范围之外的字符,则在某些浏览器配置中使用乱码文本进行渲染。文件的字符编码需要在传输协议中声明,或者文件需要使用字节顺序标记作为编码签名。 / I>“

- 更新配置 -

<context:property-placeholder location="classpath:/mule.properties"/>
<custom-transformer class="id.co.zire.ebs.mule.transformer.RouteTransformer" name="RouteTransformer" doc:name="RouteTransformer"/>
<http:connector name="STD_HTTP_CONNECTOR" enableCookies="true" validateConnections="true" clientSoTimeout="20000" serverSoTimeout="10000" doc:name="HTTP\HTTPS">
    <dispatcher-threading-profile maxThreadsActive="50" maxBufferSize="150"/>
    <reconnect count="3" frequency="2000"/>
</http:connector>
<flow name="HTTPBridgeFlow" doc:name="HTTPBridgeFlow">
    <composite-source>
        <inbound-endpoint exchange-pattern="request-response" address="http://${local.server}/${user.context}/" encoding="ISO-8859-1" connector-ref="STD_HTTP_CONNECTOR" doc:name="User Endpoint"/>
        <inbound-endpoint exchange-pattern="request-response" address="http://${local.server}/${cms.context}/" encoding="ISO-8859-1" connector-ref="STD_HTTP_CONNECTOR" doc:name="CMS Endpoint"/>
        <inbound-endpoint exchange-pattern="request-response" address="http://${local.server}/${ads.context}/" encoding="ISO-8859-1" connector-ref="STD_HTTP_CONNECTOR" doc:name="Ads Endpoint"/>
    </composite-source>
    <echo-component doc:name="Echo"/>
    <transformer ref="RouteTransformer" doc:name="Transform Header"/>
    <set-property propertyName="http.method" value="#[header:INBOUND:http.method]" doc:name="Copy HTTP method"/>
    <flow-ref name="HTTPResponseFlow" doc:name="HTTP Flow Reference"/>
</flow>
<sub-flow name="HTTPResponseFlow" doc:name="HTTPResponseFlow">
    <logger message="Payload Output : #[message.payload]" level="INFO" doc:name="Logger"/>
    <choice doc:name="Choice">
        <when expression="message.inboundProperties['http.context.path'] contains '${user.context}'">
            <processor-chain>
                <http:outbound-endpoint exchange-pattern="request-response" address="http://${user.server}/#[message.inboundProperties['http.relative.path']]" responseTimeout="120000" doc:name="HTTP User"/>
            </processor-chain>
        </when>
        <when expression="message.inboundProperties['http.context.path'] contains '${cms.context}'">
            <processor-chain>
                <http:outbound-endpoint exchange-pattern="request-response" address="http://${cms.server}/#[message.inboundProperties['http.relative.path']]" responseTimeout="120000" doc:name="HTTP CMS"/>
            </processor-chain>
        </when>
        <when expression="message.inboundProperties['http.context.path'] contains '${ads.context}'">
            <processor-chain>
                <http:outbound-endpoint exchange-pattern="request-response" address="http://${ads.server}/#[message.inboundProperties['http.relative.path']]" responseTimeout="120000" doc:name="HTTP Ads"/>
            </processor-chain>
        </when>
    </choice>
    <echo-component doc:name="Echo"/>
    <message-properties-transformer doc:name="Set Cross-Domain Request Allowed">
        <add-message-property key="Access-Control-Allow-Origin" value="*"/>
        <add-message-property key="Access-Control-Allow-Methods" value="GET, POST, OPTIONS"/>
        <add-message-property key="Access-Control-Max-Age" value="1000"/>
        <add-message-property key="Access-Control-Allow-Headers" value="Content-Type"/>
    </message-properties-transformer>
</sub-flow>

好的,现在我已经更改了大部分配置,现在我遇到了在HTTP POST消息体中传递包含的二进制数据的问题。 Mule似乎在将字节传递到出站端点之前更改字节。我已经创建了一个自定义转换器来手动获取有效负载并解析有效负载中的二进制数据(有效负载类型是String),但是已经更改了从有效负载中检索到的二进制数据。例如,下面是十六进制原始文件字节的一部分:

ff d8 ff e0 00 10 4a 46(ÿØÿà..JF)

但是Mule转换成:

3f 3f 3f 3f 00 10 4a 46(???? JF)

我认为这是编码问题,也许Mule会自动将其转换为UTF-8

- RouteTransformer.java -

public class RouteTransformer extends AbstractMessageTransformer{
    private static final String MULE_CONFIG = "/mule.properties";
    private static final String CLIENT_IP = "MULE_REMOTE_CLIENT_ADDRESS";
    private static final String CLIENT_IP_HEADER = "Client-Ip";
    private static final String IP_REGEX = "/?((\\d{1,3})\\.(\\d{1,3})\\.(\\d{1,3})\\.(\\d{1,3}))(:(\\d{1,5}))?";
    private final String[] PASSING_HEADER;

    public RouteTransformer() throws IOException{
        Properties prop = new Properties();
        prop.load(getClass().getResourceAsStream(MULE_CONFIG));
        PASSING_HEADER = prop.getProperty("passing-header").split("\\s*,\\s*");
    }

    public Object transformMessage(MuleMessage message, String outputEncoding) throws TransformerException{
        // Copy 'passing' header
        for(int i=PASSING_HEADER.length; --i>=0; ){
            String headerName = PASSING_HEADER[i];
            Object val = message.getInboundProperty(headerName);
            if(headerName.equals(CLIENT_IP)){
                String s = (String) val;
                Pattern p = Pattern.compile(IP_REGEX);
                Matcher m = p.matcher(s);
                if(!m.matches()) continue;
                else{
                    headerName = CLIENT_IP_HEADER;
                    val = m.group(1);
                }
            }
            if(val != null) message.setOutboundProperty(headerName, val);
        }

        // Routing message
        String requestString = message.getInboundProperty("http.request");
        String contextPath = message.getInboundProperty("http.context.path");
        if(requestString != null && contextPath != null)
            message.setOutboundProperty("http.real.path", requestString.substring(contextPath.length()));

        return message;
    }
}

- Multipart / form-data示例 -

-----------------------------20037128598723
Content-Disposition: form-data; name="name"

Angga
-----------------------------20037128598723
Content-Disposition: form-data; name="adsImage"; filename="Penguins.jpg"
Content-Type: image/jpeg

ÿØÿà..JF -- and the rest of bytes --

我希望有人能提出一些解决方案。 感谢

2 个答案:

答案 0 :(得分:2)

在您的内容类型中,您必须添加charset=utf-8

response.setContentType("application/json; charset=utf-8")

Content-Type: application/json; charset=utf-8

答案 1 :(得分:0)

我想知道您所遇到的问题是否与出站HTTP互动中缺少内容类型(或其默认值)有关。

尝试添加消息属性转换器(或读取此的3.3.x用户的副本属性消息处理器)以复制&#34; Content-Type&#34;从入境范围到出境范围的财产。

另外,严格要求&#39;为此,配置此端点以使用POST方法。