开始学mule,还不知道原理,架构,在使用中摸索:
这次学到了http端点和Java组件,很简单的图:
xml为:
Java组件代码:
public class HttpProcess{
public String sayHello(String path){
return "hello1 " + path;
}
} 很简单的Java组件,但是问题来了,当我请求http://localhost:8081/haogrgr的时候
为什么会输出"hello1 /haogrgr" 问题:
1.为什么会调用我的sayHello方法,在那里配置的?
2.为什么参数是/haogrgr
3.返回值怎么成了响应正文.
带着这几个疑惑,我开始看源码,最后发现 问题1:
之所以会调用sayHello方法,是因为,mule会根据请求参数列表来匹配方法. 问题2:
浏览器产生的请求会转换为一个org.mule.transport.http.HttpRequest对象,
然后mule根据这个对象创建mule消息这里是DefaultMuleMessage类型的消息.
然后mule会设置消息的payload为请求正文(流类型的对象),如果请求正文为空,则将payload设置为请求路径.
然后调用Java组件时,会将消息的payload值设置为Java组件方法调用的参数,根据参数找到匹配的方法,
然后反射调用. 问题3:
反射调用的结果,mule会判断结果的类型,额,我上代码吧...ponent.AbstractComponent
protected MuleEvent createResultEvent(MuleEvent event, Object result) throws MuleException
{
if (result instanceof MuleMessage)
{
return new DefaultMuleEvent((MuleMessage) result, event);
}
else if (result instanceof VoidResult)
{
return event;
}
else if (result != null)
{
event.getMessage().applyTransformers(
event,
Collections. singletonList(new TransformerTemplate(
new TransformerTemplate.OverwitePayloadCallback(result))));
return event;
}
else
{
DefaultMuleMessage emptyMessage = new DefaultMuleMessage(NullPayload.getInstance(), muleContext);
emptyMessage.propagateRootId(event.getMessage());
return new DefaultMuleEvent(emptyMessage, event);
}
} 因为返回值是String,所以他会返回一个event,然后这个会传来传去,然后又是一扒拉拦截器,然后又是事务拦截啥啥啥的,
不知道你晕没晕,反正我不行了...
最后,终于来了:org.mule.transport.http.HttpMessageProcessTemplate.sendResponseToClient
@Override
public void sendResponseToClient(MuleEvent responseMuleEvent) throws MuleException
{
try
{
if (logger.isTraceEnabled())
{
logger.trace("Sending http response");
}
MuleMessage returnMessage = responseMuleEvent == null ? null : responseMuleEvent.getMessage();
Object tempResponse;
if (returnMessage != null)
{
tempResponse = returnMessage.getPayload();
}
else
{
tempResponse = NullPayload.getInstance();
}
// This removes the need for users to explicitly adding the response transformer
// ObjectToHttpResponse in their config
HttpResponse response;
if (tempResponse instanceof HttpResponse)
{
response = (HttpResponse) tempResponse;
}
else
{
response = transformResponse(returnMessage);
}
response.setupKeepAliveFromRequestVersion(request.getRequestLine().getHttpVersion());
HttpConnector httpConnector = (HttpConnector) getMessageReceiver().getEndpoint().getConnector();
response.disableKeepAlive(!httpConnector.isKeepAlive());
Header connectionHeader = request.getFirstHeader("Connection");
if (connectionHeader != null)
{
String value = connectionHeader.getValue();
boolean endpointOverride = getEndpointKeepAliveValue(getMessageReceiver().getEndpoint());
if ("keep-alive".equalsIgnoreCase(value) && endpointOverride)
{
response.setKeepAlive(true);
if (response.getHttpVersion().equals(HttpVersion.HTTP_1_0))
{
connectionHeader = new Header(HttpConstants.HEADER_CONNECTION, "Keep-Alive");
response.setHeader(connectionHeader);
}
}
else if ("close".equalsIgnoreCase(value))
{
response.setKeepAlive(false);
}
}
try
{
httpServerConnection.writeResponse(response,getThrottlingHeaders());
}
catch (Exception e)
{
failureSendingResponse = true;
}
if (logger.isTraceEnabled())
{
logger.trace("HTTP response sent successfully");
}
}
catch (Exception e)
{
if (logger.isDebugEnabled())
{
logger.debug("Exception while sending http response");
logger.debug(e);
}
throw new MessagingException(responseMuleEvent,e);
}
} 将返回结果写回客户端,好像也没说明白哦...
最后的消息的payload为httpresponse类型,是经过一系列的转换而来的,
创建 org.mule.transport.http.HttpResponse对象时,设置body为mule消息的payload
public void setBody(MuleMessage msg) throws Exception
{
if (msg == null) return;
//TODO MULE-5005 response attachments
// if(msg.getOutboundAttachmentNames().size() > 0)
// {
// setBody(createMultipart());
// setHeader(new Header(HttpConstants.HEADER_CONTENT_TYPE, MimeTypes.MULTIPART_MIXED));
// return;
// }
Object payload = msg.getPayload();
if (payload instanceof String)
{
setBody(payload.toString());
}
else if (payload instanceof NullPayload)
{
return;
}
else if (payload instanceof byte[])
{
setBody((byte[]) payload);
}
else
{
setBody(msg.getPayload(DataTypeFactory.create(OutputHandler.class)));
}
} 所以响应正文为方法返回值...
还有很多不明白的地方,也许有讲错的地方,也许我这们弄根本就是错误的,希望大家指出来...
还有,如果组将实现了org.mule.api.lifecycle.Callable接口后,就只会调用onCall方法了...具体原因不名
这个问题还是等我了解mule架构后再来,mark下.