我在配置 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/