我的简单Web服务接收XML文档的Zip文件,我尝试使用XSD架构文件验证XML。以下是代码段
Schema schema = BlahSchemaFactory.newSchema("Blah.xsd");
Validator validator = schema.newValidator();
BlahErrorHandler eh = new BlahErrorHandler();
validator.setErrorHandler(eh);
ZipInputStream zis = new ZipInputStream(new ByteArrayInputStream(zipFileContentAsBytes));
zis.getNextEntry();
Source xmlSource = new StreamSource(zis);
validator.validate(xmlSource);
BlahSchemaFactory 是一个单例,每个传递的XSD文件只帮助创建一次Schema对象。现在,当几个HTTP线程通过上面的代码传递时出现问题。它们在validate()方法的代码深处相互阻塞。
以下是从HP Diagnostic工具获取的堆栈跟踪。
"blah_thread_77" Id=472 in BLOCKED on lock=org.apache.xerces.impl.xpath.regex.RegularExpression@3c9d97f9
owned by d1_thread_237 Id=21648
at org.apache.xerces.impl.xpath.regex.RegularExpression.matches(Unknown Source)
at org.apache.xerces.impl.xpath.regex.RegularExpression.matches(Unknown Source)
at org.apache.xerces.impl.dv.xs.XSSimpleTypeDecl.getActualValue(Unknown Source)
at org.apache.xerces.impl.dv.xs.XSSimpleTypeDecl.validate(Unknown Source)
at org.apache.xerces.impl.xs.XMLSchemaValidator.processOneAttribute(Unknown Source)
at org.apache.xerces.impl.xs.XMLSchemaValidator.processAttributes(Unknown Source)
at org.apache.xerces.impl.xs.XMLSchemaValidator.handleStartElement(Unknown Source)
at org.apache.xerces.impl.xs.XMLSchemaValidator.emptyElement(Unknown Source)
at org.apache.xerces.impl.XMLNSDocumentScannerImpl.scanStartElement(Unknown Source)
at org.apache.xerces.impl.XMLDocumentFragmentScannerImpl$FragmentContentDispatcher.dispatch(Unknown Source)
at org.apache.xerces.impl.XMLDocumentFragmentScannerImpl.scanDocument(Unknown Source)
at org.apache.xerces.parsers.XML11Configuration.parse(Unknown Source)
at org.apache.xerces.parsers.XML11Configuration.parse(Unknown Source)
at org.apache.xerces.jaxp.validation.StreamValidatorHelper.validate(Unknown Source)
at org.apache.xerces.jaxp.validation.ValidatorImpl.validate(Unknown Source)
at javax.xml.validation.Validator.validate(Validator.java:124)
at BlahPackage.BlahClass.uploadSaveFileRecord(BlahRecord.java:77)
at sun.reflect.GeneratedMethodAccessor210.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:601)
at org.jboss.ws.common.invocation.AbstractInvocationHandlerJSE.invoke(AbstractInvocationHandlerJSE.java:111)
at org.jboss.wsf.stack.cxf.JBossWSInvoker._invokeInternal(JBossWSInvoker.java:181)
at org.jboss.wsf.stack.cxf.JBossWSInvoker.invoke(JBossWSInvoker.java:127)
at org.apache.cxf.interceptor.ServiceInvokerInterceptor$1.run(ServiceInvokerInterceptor.java:58)
at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:471)
问题:有什么方法可以避免线程上的阻塞吗?请提出建议!
答案 0 :(得分:0)
以下是在尝试使用XSD架构验证XML时解决线程阻塞问题的代码段。你需要:
而不是打电话 BlahObject.class.getClassLoader()的getResource(schemaFileOnClassPath) 使用某种类型的Singleton来获取XSD的URL一次,否则你会遇到线程阻塞,类加载器试图找到它 资源(这是使用HP诊断工具识别的)
SchemaFactory schemaFactory = SchemaFactory.newInstance(XMLConstants.W3C_XML_SCHEMA_NS_URI);
URL schemaURL = BlahSchemaSingleton.getSchemaURL("Blah.xsd");
Schema schema = null;
synchronized(schemaFactory) {
schema = schemaFactory.newSchema(schemaURL);
}
Validator validator = schema.newValidator();
BlahErrorHandler eh = new BlahErrorHandler();
validator.setErrorHandler(eh);
ZipInputStream zis = new ZipInputStream(new ByteArrayInputStream(zipFileContentAsBytes));
zis.getNextEntry();
Source xmlSource = new StreamSource(zis);
validator.validate(xmlSource);