HTTP Endpoint
重写mule源代码中的HttpMultipartMuleMessageFactory.java
package com.rakuten.api.cabinet.factory;
import java.io.IOException;
import java.util.Collection;
import java.util.Map;
import javax.activation.DataHandler;
import org.mule.DefaultMuleMessage;
import org.mule.api.MuleContext;
import org.mule.transport.http.HttpMuleMessageFactory;
import org.mule.transport.http.HttpRequest;
import org.mule.transport.http.multipart.MultiPartInputStream;
import org.mule.transport.http.multipart.Part;
import org.mule.transport.http.multipart.PartDataSource;
import com.rakuten.api.cabinet.constants.CabinetFlowConstants;
/**
*
* Corretion Alexis ANASTASSIADES ___ alexis - at - ezanas.com
* @author ldns_zhuling
*/
public class HttpMultipartMuleMessageFactory extends HttpMuleMessageFactory {
/** parts */
private Collection<Part> parts;
/**
*
* @param context context
*/
public HttpMultipartMuleMessageFactory(MuleContext context) {
super(context);
}
@Override
protected Object extractPayloadFromHttpRequest(HttpRequest httpRequest) throws IOException
{
Object body = null;
String contentType = httpRequest.getContentType();
if (contentType.toLowerCase().contains("multipart/form-data")) {
// modify multipart/form-data to lower case
// 可能出现大小写的contentType,需要全部转为小写的
contentType = contentType.replace(contentType.substring(0,
CabinetFlowConstants.CONTENT_TYPE_MULTIPART_PART.length()),
CabinetFlowConstants.CONTENT_TYPE_MULTIPART_PART);
MultiPartInputStream in = new MultiPartInputStream(httpRequest.getBody(),
contentType, null);
// We need to store this so that the headers for the part can be read
parts = in.getParts();
for (Part part : parts) {
//将名为xml的附件内容放到message.payload中,这个根据项目传进来的附件名进行修改
if ("xml".equals(part.getName())) {
body = part.getInputStream();
break;
}
}
} else {
body = super.extractPayloadFromHttpRequest(httpRequest);
}
return body;
}
@Override
protected void addAttachments(DefaultMuleMessage message, Object transportMessage) throws Exception {
if (parts != null) {
try {
for (Part part : parts) {
//将除了名为payload的其他所有的附件放到header中
//建议在附件使用完后,将附件删除,否则返回会出现错误
if (!"payload".equals(part.getName())) {
message.setInboundProperty(part.getName(), new DataHandler(new PartDataSource(part)));
}
}
} finally {
// Attachments are the last thing to get processed
parts.clear();
parts = null;
}
}
}
@Override
protected void convertMultiPartHeaders(Map<String, Object> headers) {
}
}
Servlet Endpoint
需要重写ServletMuleMessageFactory.java
package com.rakuten.api.cabinet.factory;
import java.util.Collection;
import javax.activation.DataHandler;
import javax.servlet.http.HttpServletRequest;
import org.mule.DefaultMuleMessage;
import org.mule.api.MuleContext;
import org.mule.transport.http.multipart.MultiPartInputStream;
import org.mule.transport.http.multipart.Part;
import org.mule.transport.http.multipart.PartDataSource;
import org.mule.transport.servlet.ServletMuleMessageFactory;
import com.rakuten.api.cabinet.constants.CabinetFlowConstants;
/**
*
* Corretion Alexis ANASTASSIADES ___ alexis - at - ezanas.com
* @author ldns_zhuling
*/
public class ServletMultipartMuleMessageFactory extends ServletMuleMessageFactory {
/** parts */
private Collection<Part> parts;
/**
*
* @param context context
*/
public ServletMultipartMuleMessageFactory(MuleContext context) {
super(context);
}
@Override
protected Object extractPayloadFromPostRequest(HttpServletRequest request) throws Exception
{
Object body = null;
String contentType = request.getContentType();
if (contentType.toLowerCase().contains(CabinetFlowConstants.CONTENT_TYPE_MULTIPART_PART)) {
// modify multipart/form-data to lower case
contentType = contentType.replace(contentType.substring(0,
CabinetFlowConstants.CONTENT_TYPE_MULTIPART_PART.length()),
CabinetFlowConstants.CONTENT_TYPE_MULTIPART_PART);
MultiPartInputStream in = new MultiPartInputStream(request.getInputStream(),
contentType, null);
// We need to store this so that the headers for the part can be read
parts = in.getParts();
for (Part part : parts) {
if ("xml".equals(part.getName())) {
body = part.getInputStream();
break;
}
}
} else {
//原代码中在获取body之前加了这句“request.getParameterNames();”
//这句必须删掉,否则获取不到body,因为InputStream不能重复读取。
body = request.getInputStream();
}
return body;
}
@Override
protected void addAttachments(DefaultMuleMessage message, Object transportMessage) throws Exception {
if (parts != null) {
try {
for (Part part : parts) {
if (!"payload".equals(part.getName())) {
message.setInboundProperty(part.getName(), new DataHandler(new PartDataSource(part)));
}
}
} finally {
// Attachments are the last thing to get processed
parts.clear();
parts = null;
}
}
}
}
然后需要在connector中调用该factory
<http:connector name="defaultconnector" cookieSpec="netscape"
doc:name="HTTP\HTTPS" receiveBacklog="0" receiveBufferSize="0"
sendBufferSize="0" socketSoLinger="0" validateConnections="true">
<dispatcher-threading-profile
maxBufferSize="0" maxThreadsActive="${maximum.concurrency}"
maxThreadsIdle="${maximum.concurrency}" poolExhaustedAction="WAIT"
threadWaitTimeout="${inner.response.timeout}" />
<service-overrides sessionHandler="org.mule.session.NullSessionHandler" messageFactory="com.rakuten.api.cabinet.factory.HttpMultipartMuleMessageFactory"/>
</http:connector>
<servlet:connector name="Servlet" doc:name="Servlet">
<service-overrides messageFactory="com.rakuten.api.coupon.factory.ServletMuleMessageFactory"/>
</servlet:connector>
本文介绍如何重写 MuleSoft 中的 HttpMultipartMuleMessageFactory 和 ServletMultipartMuleMessageFactory 类,以改进 HTTP 和 Servlet 终端的数据处理方式。通过对 multipart/form-data 的特殊处理,确保 XML 数据作为 payload 被正确读取,并将其他附件存储为 header。同时介绍了如何在配置文件中引用这些自定义工厂。
3090

被折叠的 条评论
为什么被折叠?



