如何在mule-esb中检索Schema Validation错误结果

时间:2013-11-01 11:38:29

标签: mule mule-studio mule-el

在Mule中,我正在尝试针对XSD验证XML。

在我的流程中,我正在使用与消息过滤器组件嵌套的schema-validation-filter组件并按预期工作。

但我的问题是,如果XML失败,我如何捕获记录器组件中的错误详细信息并根据需要导航流的结果。

基本上我正在寻找 MEL来在控制台上打印错误描述

注意:“returnResult”设置为false,因为我需要对XML进行进一步的操作。

这是我的配置流程:

<?xml version="1.0" encoding="UTF-8"?>

<mule xmlns:http="http://www.mulesoft.org/schema/mule/http" xmlns:file="http://www.mulesoft.org/schema/mule/file" xmlns:jms="http://www.mulesoft.org/schema/mule/jms" xmlns:tracking="http://www.mulesoft.org/schema/mule/ee/tracking" xmlns:mulexml="http://www.mulesoft.org/schema/mule/xml" xmlns:vm="http://www.mulesoft.org/schema/mule/vm" 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" version="EE-3.4.0" 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/vm http://www.mulesoft.org/schema/mule/vm/current/mule-vm.xsd
http://www.mulesoft.org/schema/mule/xml http://www.mulesoft.org/schema/mule/xml/current/mule-xml.xsd
http://www.mulesoft.org/schema/mule/ee/tracking http://www.mulesoft.org/schema/mule/ee/tracking/current/mule-tracking-ee.xsd
http://www.mulesoft.org/schema/mule/jms http://www.mulesoft.org/schema/mule/jms/current/mule-jms.xsd
http://www.mulesoft.org/schema/mule/file http://www.mulesoft.org/schema/mule/file/current/mule-file.xsd
http://www.mulesoft.org/schema/mule/http http://www.mulesoft.org/schema/mule/http/current/mule-http.xsd">
    <mulexml:schema-validation-filter schemaLocations="D:\MuleStudio\workspace\exceptiontest\src\test\resources\sample.xsd" returnResult="false" name="Schema_Validation" doc:name="Schema Validation"/>

    <flow name="ExceptionTestFlow2" doc:name="ExceptionTestFlow2">
        <http:inbound-endpoint exchange-pattern="one-way" host="localhost" port="8081" path="dataQ" doc:name="HTTP"/>
        <expression-filter expression="#[message.payload != '/favicon.ico' ]" doc:name="Expression does't allow /favicon.ico"/>
        <set-payload value="&lt;data&gt;
 &lt;books&gt;
  &lt;book edition='1.0'&gt;
   &lt;auth&gt; auth&lt;/auth&gt;
   &lt;title&gt;title&lt;/title&gt;
   &lt;pulbisher&gt;pub&lt;/pulbisher&gt;
  &lt;/book&gt;
 &lt;/books&gt;
&lt;/data&gt;
" doc:name="XML is set as payload tp the current flow"/>
        <logger message="::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: Actual Flow Started :::::::::::::::::::::::::::::::::::::::::::::::::" level="INFO" doc:name="indicates Actual Flow Started Logger"/>
        <logger message="paylad is  :::: #[payload] :::::" level="INFO" doc:name="Prints current Payload"/>
        <vm:outbound-endpoint exchange-pattern="one-way" path="dataQ" doc:name="VMQ_stores current xml which needs to be validated_senderQ"/>
    </flow>
    <flow name="ExceptionTestFlow1" doc:name="ExceptionTestFlow1">
        <vm:inbound-endpoint exchange-pattern="one-way" path="dataQ" doc:name="VMQ_stores current xml which needs to be validated_receiverQ"/>
        <logger message="::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: Flow Started :::::::::::::::::::::::::::::::::::::::::::::::::" level="DEBUG" doc:name="indicates Flow Started Logger"/>
        <message-filter  doc:name="filter to validate xml against xsd" throwOnUnaccepted="true">
            <filter ref="Schema_Validation"/>
        </message-filter>
        <logger message=" validation is true and the payload is :::: #[payload]" level="INFO" doc:name="current Payload"/>
        <logger message="::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: End of Actual Flow:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::" level="INFO" doc:name="indicates Flow End Logger"/>
        <choice-exception-strategy doc:name="Choice Exception Strategy">
            <catch-exception-strategy when="exception.causedBy(org.mule.api.routing.filter.FilterUnacceptedException)" enableNotifications="false" doc:name="FilterUnacceptedException">
                <logger message="::::::::::::::::::::::::::::::::::: in FilterUnacceptedException :::::::::::::::::::::::::" level="ERROR" doc:name="indicates FilterUnacceptedException Flow Started Logger"/>
                <set-payload value="The request cannot be processed, the error is #[exception.getMessage()]" doc:name="Set Payload"/> <!-- [1] -->
                <set-property propertyName="http.status" value="500" doc:name="Property"/>
                <logger message=":::::::::::: end of FilterUnacceptedException with a payload as  #[message.payload] ::::::::::::" level="INFO" doc:name="indicates FilterUnacceptedException End Logger"/> <!-- [2] -->
            </catch-exception-strategy>
            <catch-exception-strategy enableNotifications="false" doc:name="default">
                <logger message=":::::::::::::::::::::: in default::::::::::::::::::::::::::::" level="ERROR" doc:name="indicates defaultException Flow Started Logger"/>
                <set-payload value="The request cannot be processed, the error is #[exception.getSummaryMessage()]" doc:name="Set Payload"/>
                <logger message="::::::::::::::::::::::::::::::::::::::::::::: END of Default Exception :::::::::::::::::::::::::::::::::::" level="INFO" doc:name="indicates DefaultException End Logger"/> <!-- [1] -->
 <!-- [2] -->
            </catch-exception-strategy>
        </choice-exception-strategy>
    </flow>
    <flow name="Flow_If_XML_not_valid" doc:name="Flow_If_XML_not_valid">
        <logger message=":::::::::::::::::::::::::::: #[payload] :::::::::::::: onThrow ::::::" level="INFO" doc:name="Should Print  error description"/>
    </flow>
</mule>

添加了一个提供以下输出的异常策略:

消息已被过滤器拒绝。消息有效内容的类型为:String 代码:MULE_ERROR - 2

异常堆栈是: 1.消息已被过滤器拒绝。消息有效内容的类型为:String(org.mule.api.routing.filter.FilterUnacceptedException)  ...... http://www.mulesoft.org/docs/site/current3/apidocs/org/mule/api/routing/filter/FilterUnacceptedException.html)..

我需要能够确定导致问题的字段。

3 个答案:

答案 0 :(得分:0)

由于过滤器配置为不接受,因此您需要有一个异常策略来处理错误。

阅读:http://www.mulesoft.org/documentation/display/current/Error+Handling

答案 1 :(得分:0)

您没有,请参阅SchemaValidationFilter源文件。 SAXException只是catch和log(在调试中)。我认为你需要制作自己的SchemaValidationFilter。 (继承Mule Validator)

答案 2 :(得分:-1)

package what.the.fuck.customFilter;

import java.io.IOException;

import javax.xml.transform.Source;
import javax.xml.transform.dom.DOMResult;

import org.mule.api.MuleMessage;
import org.mule.api.transport.PropertyScope;
import org.mule.module.xml.filters.SchemaValidationFilter;
import org.xml.sax.SAXException;

public class SchemaValidationFilterWithTrace extends SchemaValidationFilter {

    public final static String SAX_ERROR_PROPERTIES = "SAX_ERROR_PROPERTIES";
    public final static boolean RETURN_RESULT = false;
    public final static String SCHEMA_LOCATION = "what.the.fuck.xsd";

    public SchemaValidationFilterWithTrace(){
        super();
        super.setReturnResult(false);
        super.setSchemaLocations(SCHEMA_LOCATION);
    }


    /**
     * Accepts the message if schema validation passes.
     * 
     * @param message The message.
     * @return Whether the message passes schema validation.
     */
    @Override
    public boolean accept(MuleMessage message)
    {
        Source source;
        try
        {
            source = loadSource(message);
        }
        catch (Exception e)
        {
            if (e instanceof RuntimeException)
            {
                throw (RuntimeException) e;
            }

            if (logger.isInfoEnabled())
            {
                logger.info("SchemaValidationFilter rejected a message because there was a problem interpreting the payload as XML.", e);
            }
            return false;
        }

        if (source == null)
        {
            if (logger.isInfoEnabled())
            {
                logger.info("SchemaValidationFilter rejected a message because the XML source was null.");
            }
            return false;
        }


        DOMResult result = null;

        try
        {
            if (super.isReturnResult()) 
            {
                result = new DOMResult();
                createValidator().validate(source, result);
            }
            else 
            {
                createValidator().validate(source);
            }
        }
        catch (SAXException e)
        {
            message.setProperty(SAX_ERROR_PROPERTIES, e.getMessage(), PropertyScope.OUTBOUND);
            if (logger.isDebugEnabled())
            {
                logger.debug(
                    "SchemaValidationFilter rejected a message because it apparently failed to validate against the schema.",
                    e);
            }
            return false;
        }
        catch (IOException e)
        {
            if (logger.isInfoEnabled())
            {
                logger.info(
                    "SchemaValidationFilter rejected a message because there was a problem reading the XML.",
                    e);
            }
            return false;
        }
        finally 
        {
            if (result != null && result.getNode() != null)
            {
                message.setPayload(result.getNode());
            }
        }

        if (logger.isDebugEnabled())
        {
            logger.debug("SchemaValidationFilter accepted the message.");
        }

        return true;
    }

}