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

标签 http mule

我在配置 Mule 3.2 时遇到问题,它基本上接收 HTTP POST(多部分/表单数据)并路由有效负载,然后通过 HTTP POST(多部分/表单数据)发送有效负载。究竟如何在 Mule 中完成此类任务?

以下是我的配置的一部分

<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 范围之外的字符,在某些浏览器配置中会呈现乱码。需要在传输协议(protocol)中声明文件的字符编码或者文件需要使用字节顺序标记作为编码签名。"

-- 更新的配置 --

<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 似乎在将字节传递到出站端点之前更改字节。我创建了一个自定义转换器来手动获取有效负载并解析来自有效负载的二进制数据(顺便说一句,有效负载类型是字符串),但从有效负载检索到的二进制数据已经被更改。例如下面是十六进制的原始文件字节的一部分:

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;
    }
}

-- 多部分/表单数据示例 --

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

希望有人能提供一些解决方案。 谢谢

最佳答案

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

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

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

关于http - 在 mule 3.2 中接收和发送 multipart/form-data,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11881750/

相关文章:

mule - 将消息有效负载设置为 session 变量

java - Android 中仅客户端套接字编程

http - 如何创建一个不由轮询驱动的聊天服务器?

http - Flutter:我收到一个错误,指出状态为窗口小部件的对象不再出现在窗口小部件树中

java - 我在注入(inject)这些 Spring Bean 时做错了什么?使用 Autowiring

ule子流-命名约定

Mule ESB - 如何使用 POST 方法创建 HTTP 请求(一起发送参数)

http - Put 与 Post - REST

python - 从 HTTP 转义 Python 字符串

java - Mule JaxB 解码无法解析 ArrayList