工具 | 版本 |
---|---|
mule-standalone | 3.9.0 |
Anypoint-Studio | 6.4.0 |
写在前面
例子主要由一个Flow
和一个strategy(策略)
两部分构成,Flow中过滤了favicon.ico
请求,同时接受url参数type
作为判断触发不同类型异常的标识,异常的触发通过自定义的java类来控制,在Flow中出现异常后,通过Reference Exception Strategy
转到global_reference_exception_strategy
处执行,global_reference_exception_strategy
实际是Choice Exception Strategy
元素,它可以包含多个Catch Exception Strategy
来匹配不同异常类型进行处理。strategy使用自定义转换器来显示ExceptionPayload
的使用。最后调用子flow来设置paylaod用于页面输出异常类名称。
每一个Catch Exception Strategy通过Exception When中填写的表达式来匹配不同类型的异常,该表达式使用文档可在参考资料找到最下方找到
如果发布在mule环境下,可以看到{MULE_HOME}/logs/下有名为exceptionexample.log的文件,里面记录着控制台的输出信息
Flow结构图
XML文档
<?xml version="1.0" encoding="UTF-8"?>
<mule xmlns:http="http://www.mulesoft.org/schema/mule/http" xmlns="http://www.mulesoft.org/schema/mule/core" xmlns:doc="http://www.mulesoft.org/schema/mule/documentation"
xmlns:spring="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-current.xsd
http://www.mulesoft.org/schema/mule/core http://www.mulesoft.org/schema/mule/core/current/mule.xsd
http://www.mulesoft.org/schema/mule/http http://www.mulesoft.org/schema/mule/http/current/mule-http.xsd">
<http:listener-config name="HTTP_Listener_Configuration" host="0.0.0.0" port="8081" doc:name="HTTP Listener Configuration"/>
<flow name="ExceptionMainFlow">
<http:listener config-ref="HTTP_Listener_Configuration" path="/*" allowedMethods="GET" doc:name="HTTP"/>
<expression-filter expression="#[message.inboundProperties.'http.request.uri' != '/favicon.ico']" doc:name="filter favicon icon"/>
<custom-transformer class="exceptionexample.ThrowExceptionTest" doc:name="trigger exception "/>
<set-payload value="#['看到这里代表你没有碰到异常!!!']" doc:name="Set Payload"/>
<exception-strategy ref="global_reference_exception_strategy" doc:name="Reference Exception Strategy"/>
</flow>
<choice-exception-strategy name="global_reference_exception_strategy">
<catch-exception-strategy when="#[exception.causedBy(java.lang.ArithmeticException)]" doc:name="ArithmeticException_strategy">
<logger message="#['捕捉到java.lang.ArithmeticException异常!!!']" level="INFO" doc:name="logger_one"/>
<set-variable variableName="exceptionName" value="#['ArithmeticException']" doc:name="Variable"/>
<custom-transformer class="exceptionexample.CustomExceptionTransformer" doc:name="customException"/>
<flow-ref name="ExceptionHandlerFlow" doc:name="Flow Reference"/>
</catch-exception-strategy>
<catch-exception-strategy when="#[exception.causedBy(java.lang.NullPointerException)]" doc:name="NullPointerException_strategy">
<logger message="#['捕捉到java.lang.NullPointerException异常!!!']" level="INFO" doc:name="logger_two"/>
<set-variable variableName="exceptionName" value="#['NullPointerException']" doc:name="Variable"/>
<custom-transformer class="exceptionexample.CustomExceptionTransformer" doc:name="customException"/>
<flow-ref name="ExceptionHandlerFlow" doc:name="Flow Reference"/>
</catch-exception-strategy>
<catch-exception-strategy when="#[exception.causedBy(java.lang.ClassCastException)]" doc:name="ClassCastException_strategy">
<logger message="#['捕捉到java.lang.ClassCastException异常!!!']" level="INFO" doc:name="logger_three"/>
<set-variable variableName="exceptionName" value="#['ClassCastException']" doc:name="Variable"/>
<custom-transformer class="exceptionexample.CustomExceptionTransformer" doc:name="customException"/>
<flow-ref name="ExceptionHandlerFlow" doc:name="Flow Reference"/>
</catch-exception-strategy>
</choice-exception-strategy>
<sub-flow name="ExceptionHandlerFlow">
<set-payload value="#[flowVars.exceptionName]" doc:name="Set Payload"/>
</sub-flow>
</mule>
触发异常的JAVA类——ThrowExceptionTest.java
package exceptionexample;
import java.util.Map;
import org.apache.log4j.Logger;
import org.mule.api.MuleMessage;
import org.mule.api.transformer.TransformerException;
import org.mule.transformer.AbstractMessageTransformer;
public class ThrowExceptionTest extends AbstractMessageTransformer {
private static final Logger logger = Logger.getLogger(ThrowExceptionTest.class);
@Override
public Object transformMessage(MuleMessage message, String outputEncoding) throws TransformerException {
/**
* typeNum
*
* @description 1 : java.lang.ArithmeticException;
* @description 2 : java.lang.NullPointerException;
* @description 3 : java.lang.ClassCastException;
* @description 4 : no exception;
*/
Map<String,Object> map = (Map<String,Object>)message.getInboundProperty("http.query.params");
int typeNum = Integer.parseInt(map.get("type").toString());
switch (typeNum) {
case 1:
int i = 1 / 0;
break;
case 2:
String ii = null;
ii.toString();
break;
case 3:
Object iii = new Integer(0);
iii = (String) iii;
break;
default:
break;
}
return null;
}
}
自定义Transformer使用ExceptionPayload——CustomExceptionTransformer.java
package exceptionexample;
import java.io.PrintWriter;
import java.util.Map;
import java.util.Set;
import org.apache.log4j.Logger;
import org.mule.api.ExceptionPayload;
import org.mule.api.MuleMessage;
import org.mule.api.transformer.TransformerException;
import org.mule.transformer.AbstractMessageTransformer;
public class CustomExceptionTransformer extends AbstractMessageTransformer {
private static final Logger LOGGER = Logger.getLogger(CustomExceptionTransformer.class);
@Override
public Object transformMessage(MuleMessage message, String outputEncoding) throws TransformerException {
LOGGER.info("*******************************");
//获取ExceptionPayload对象
ExceptionPayload ep = message.getExceptionPayload();
LOGGER.info("异常信息描述"+ep.getMessage());
LOGGER.info("异常CODE"+ep.getCode());
Map<String, Object> epi = ep.getInfo();
Set<String> set = epi.keySet();
for(String k : set) {
LOGGER.info("键:"+k+",值:"+epi.get(k));
}
Throwable t = ep.getException();
LOGGER.info("printStackTrace信息:");
//打印堆栈信息
t.printStackTrace();
LOGGER.info("*******************************");
return null;
}
}
Mule invokes a Messaging Exception Strategy whenever an exception is thrown within a flow (i.e., whenever a message is involved, exceptions are handled by messaging exception strategies).
Each flow can contain only one exception strategy. However this can be a choice exception strategy that then refers to other nested exception strategies.
Choice exception strategies can contain one or more catch and/or rollback exception >strategies. (Rollback and catch exception strategies cannot, however, contain other exception strategies.)
Each exception strategy can contain any number of message processors.
The exception strategy message processors should not throw exceptions, because you cannot create a nested exception strategy for these message processors.
运行
访问http://localhost:8081/?type=1,页面显示ArithmeticException
参考资料
mule关于异常处理的文档
mulesoft关于异常的博客
catch exception strategy使用(表达式示例)