Java ApacheCamel:ValidatingProcessor:XSD验证
我正在尝试创建一个包并在ServiceMix中运行它。 我遇到了一个问题,非常感谢您的帮助 我想做的是: 从CXF端点生成SOAP消息,并使用Apache ServiceMix 5.0.0(Camel 2.12.3)根据XSD模式验证这些消息 我所做的: 实现了一个路由,该路由从CXF端点生成消息,然后对其进行验证 路由的Java ApacheCamel:ValidatingProcessor:XSD验证,java,apache-camel,cxf,xsd-validation,apache-servicemix,Java,Apache Camel,Cxf,Xsd Validation,Apache Servicemix,我正在尝试创建一个包并在ServiceMix中运行它。 我遇到了一个问题,非常感谢您的帮助 我想做的是: 从CXF端点生成SOAP消息,并使用Apache ServiceMix 5.0.0(Camel 2.12.3)根据XSD模式验证这些消息 我所做的: 实现了一个路由,该路由从CXF端点生成消息,然后对其进行验证 路由的配置方法: private RouteBuilder getInputRoute() { SoapValidatingProcessor soapValidating
配置方法:
private RouteBuilder getInputRoute() {
SoapValidatingProcessor soapValidatingProcessor = new SoapValidatingProcessor();
inputRoute = new RouteBuilder() {
@Override
public void configure() throws Exception {
from(cxfEndpointInId())
.convertBodyTo(java.lang.String.class, "UTF-8")
.onException(org.apache.camel.ValidationException.class)
.log(LoggingLevel.INFO, LOG_NAME, "Invalid message received!")
.handled(true)
.stop()
.end()
.bean(soapValidatingProcessor).id("SoapHeaderValidatingProcessor")
.to("browse:foo")
}
已创建验证处理器:
public class SoapValidatingProcessor {
private final String SCHEMA = "schema.xsd";
public SoapValidatingProcessor() {
validatingProcessor = new ValidatingProcessor();
validatingProcessor.setFailOnNullHeader(false);
validatingProcessor.setFailOnNullBody(false);
}
@Handler
public void validate(Exchange exchange) throws Exception {
Resource validationSchema = context.getApplicationContext().getResource(SCHEMA);
validatingProcessor.setSchemaUrl(validationSchema.getURL());
validatingProcessor.loadSchema();
/* Creating a new SchemaFactory instance */
SchemaFactory xmlSchema = SchemaFactory
.newInstance(XMLConstants.W3C_XML_SCHEMA_NS_URI);
validatingProcessor.setSchemaFactory(xmlSchema);
validatingProcessor.process(exchange);
}
}
问题:
Apache Camel ValidatingProcessor[1]在多重威胁中表现不佳。我正在aprox发送SOAP消息。20毫秒的间隔,我得到以下异常。如果我将发送间隔增加到200ms以上,一切都很好
2014-07-11 17:11:47,404 | WARN | ult-workqueue-18 | PhaseInterceptorChain | ? ? | 129 - org.ap
ache.cxf.cxf-api - 2.7.10 | Application {http://ws.service}WSImplService#{http://foo.bar}Update has thrown exception, unwinding now
org.apache.cxf.interceptor.Fault: FWK005 parse may not be called while parsing.
at org.apache.camel.component.cxf.CxfConsumer$1.checkFailure(CxfConsumer.java:228)[181:org.apache.camel.camel-cxf:2.12.3]
at org.apache.camel.component.cxf.CxfConsumer$1.setResponseBack(CxfConsumer.java:206)[181:org.apache.camel.camel-cxf:2.12.3]
at org.apache.camel.component.cxf.CxfConsumer$1.syncInvoke(CxfConsumer.java:140)[181:org.apache.camel.camel-cxf:2.12.3]
at org.apache.camel.component.cxf.CxfConsumer$1.invoke(CxfConsumer.java:75)[181:org.apache.camel.camel-cxf:2.12.3]
at org.apache.cxf.interceptor.ServiceInvokerInterceptor$1.run(ServiceInvokerInterceptor.java:58)[129:org.apache.cxf.cxf-api:2.7.10]
at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:471)[:1.7.0_45]
at java.util.concurrent.FutureTask.run(FutureTask.java:262)[:1.7.0_45]
at org.apache.cxf.workqueue.SynchronousExecutor.execute(SynchronousExecutor.java:37)[129:org.apache.cxf.cxf-api:2.7.10]
at org.apache.cxf.interceptor.ServiceInvokerInterceptor.handleMessage(ServiceInvokerInterceptor.java:107)[129:org.apache.cxf.cxf-api
:2.7.10]
at org.apache.cxf.phase.PhaseInterceptorChain.doIntercept(PhaseInterceptorChain.java:272)[129:org.apache.cxf.cxf-api:2.7.10]
at org.apache.cxf.phase.PhaseInterceptorChain.resume(PhaseInterceptorChain.java:242)[129:org.apache.cxf.cxf-api:2.7.10]
at org.apache.cxf.interceptor.OneWayProcessorInterceptor$1.run(OneWayProcessorInterceptor.java:144)[129:org.apache.cxf.cxf-api:2.7.1
0]
at org.apache.cxf.workqueue.AutomaticWorkQueueImpl$3.run(AutomaticWorkQueueImpl.java:428)[129:org.apache.cxf.cxf-api:2.7.10]
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145)[:1.7.0_45]
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615)[:1.7.0_45]
at org.apache.cxf.workqueue.AutomaticWorkQueueImpl$AWQThreadFactory$1.run(AutomaticWorkQueueImpl.java:353)[129:org.apache.cxf.cxf-ap
i:2.7.10]
at java.lang.Thread.run(Thread.java:744)[:1.7.0_45]
Caused by: org.xml.sax.SAXException: FWK005 parse may not be called while parsing.
at org.apache.xerces.jaxp.validation.Util.toSAXException(Unknown Source)[:]
如果validate
方法是synchronized
,我就不会得到异常,但我不希望这样
我发现:
我在这里看到[2]这个错误已经解决了。我试图为每条消息创建一个新的SchemaFactory[3]实例,但仍然没有成功。你知道为什么我还是会出错吗?我做错了什么
[1]
[2]
[3]
谢谢 您的代码不是线程安全的。在SoapValidatingProcessor
中,您正在使用共享validatingProcessor
,同时修改其状态/配置(每次加载不同的架构)
然而,在您的示例中,模式没有改变。在这种情况下,您应该只配置处理器一次(通过在启动时加载模式)
处理程序应仅调用不修改处理器状态的方法:
@Handler
public void validate(Exchange exchange) throws Exception {
validatingProcessor.process(exchange);
}
在处理任何交换之前,应配置一次状态,例如:
public SoapValidatingProcessor(CamelContext context) {
validatingProcessor = new ValidatingProcessor();
validatingProcessor.setFailOnNullHeader(false);
validatingProcessor.setFailOnNullBody(false);
Resource validationSchema = context.getApplicationContext().getResource(SCHEMA);
validatingProcessor.setSchemaUrl(validationSchema.getURL());
validatingProcessor.loadSchema();
/* Creating a new SchemaFactory instance */
SchemaFactory xmlSchema = SchemaFactory
.newInstance(XMLConstants.W3C_XML_SCHEMA_NS_URI);
validatingProcessor.setSchemaFactory(xmlSchema);
}
事实上,删除SoapValidatingProcessor
类并将所有validatingProcessor
配置移动到RouteBuilder.configure()
方法中,然后直接在路由中使用validatingProcessor
,可能会让您过得更好