Я использую CXF для предоставления веб-сервисов на основе WSDL.CxfServlet работает во встроенном Tomcat, а мои файлы wsdl и xsd находятся в JAR, который находится в пути к классам.
При импорте в файлы XSD используются относительные пути, например ./../../some.xsd
Веб-службы развернуты и работают правильно.
Однако, если я пытаюсь включить проверку схемы, я получаю следующее исключение:
java.lang.IllegalArgumentException: The resource path [/./../../some.xsd] has been normalized to [null] which is not valid
at org.apache.catalina.webresources.StandardRoot.validate(StandardRoot.java:265)
at org.apache.catalina.webresources.StandardRoot.getResource(StandardRoot.java:212)
at org.apache.catalina.webresources.StandardRoot.getResource(StandardRoot.java:206)
at org.apache.catalina.core.ApplicationContext.getResource(ApplicationContext.java:529)
at org.apache.catalina.core.ApplicationContextFacade.getResource(ApplicationContextFacade.java:201)
at org.apache.cxf.transport.servlet.ServletContextResourceResolver.resolve(ServletContextResourceResolver.java:82)
at org.apache.cxf.resource.DefaultResourceManager.findResource(DefaultResourceManager.java:120)
at org.apache.cxf.resource.DefaultResourceManager.resolveResource(DefaultResourceManager.java:58)
at org.apache.cxf.ws.addressing.EndpointReferenceUtils$SchemaLSResourceResolver.resolveResource(EndpointReferenceUtils.java:150)
at com.sun.org.apache.xerces.internal.util.DOMEntityResolverWrapper.resolveEntity(DOMEntityResolverWrapper.java:117)
at com.sun.org.apache.xerces.internal.impl.XMLEntityManager.resolveEntity(XMLEntityManager.java:1081)
at com.sun.org.apache.xerces.internal.impl.xs.XMLSchemaLoader.resolveDocument(XMLSchemaLoader.java:654)
at com.sun.org.apache.xerces.internal.impl.xs.traversers.XSDHandler.resolveSchema(XSDHandler.java:2058)
at com.sun.org.apache.xerces.internal.impl.xs.traversers.XSDHandler.constructTrees(XSDHandler.java:1014)
at com.sun.org.apache.xerces.internal.impl.xs.traversers.XSDHandler.constructTrees(XSDHandler.java:1126)
at com.sun.org.apache.xerces.internal.impl.xs.traversers.XSDHandler.constructTrees(XSDHandler.java:1126)
at com.sun.org.apache.xerces.internal.impl.xs.traversers.XSDHandler.constructTrees(XSDHandler.java:1126)
at com.sun.org.apache.xerces.internal.impl.xs.traversers.XSDHandler.parseSchema(XSDHandler.java:625)
at com.sun.org.apache.xerces.internal.impl.xs.XMLSchemaLoader.loadSchema(XMLSchemaLoader.java:610)
at com.sun.org.apache.xerces.internal.impl.xs.XMLSchemaLoader.loadGrammar(XMLSchemaLoader.java:569)
at com.sun.org.apache.xerces.internal.impl.xs.XMLSchemaLoader.loadGrammar(XMLSchemaLoader.java:535)
at com.sun.org.apache.xerces.internal.jaxp.validation.XMLSchemaFactory.newSchema(XMLSchemaFactory.java:254)
at org.apache.cxf.ws.addressing.EndpointReferenceUtils.createSchema(EndpointReferenceUtils.java:622)
at org.apache.cxf.ws.addressing.EndpointReferenceUtils.getSchema(EndpointReferenceUtils.java:668)
at org.apache.cxf.interceptor.AbstractInDatabindingInterceptor.setDataReaderValidation(AbstractInDatabindingInterceptor.java:116)
at org.apache.cxf.interceptor.AbstractInDatabindingInterceptor.getDataReader(AbstractInDatabindingInterceptor.java:90)
at org.apache.cxf.interceptor.AbstractInDatabindingInterceptor.getDataReader(AbstractInDatabindingInterceptor.java:95)
at org.apache.cxf.wsdl.interceptors.DocLiteralInInterceptor.handleMessage(DocLiteralInInterceptor.java:92)
at org.apache.cxf.phase.PhaseInterceptorChain.doIntercept(PhaseInterceptorChain.java:308)
at org.apache.cxf.transport.ChainInitiationObserver.onMessage(ChainInitiationObserver.java:121)
at org.apache.cxf.transport.http.AbstractHTTPDestination.invoke(AbstractHTTPDestination.java:267)
at org.apache.cxf.transport.servlet.ServletController.invokeDestination(ServletController.java:234)
at org.apache.cxf.transport.servlet.ServletController.invoke(ServletController.java:208)
at org.apache.cxf.transport.servlet.ServletController.invoke(ServletController.java:160)
at org.apache.cxf.transport.servlet.CXFNonSpringServlet.invoke(CXFNonSpringServlet.java:216)
at org.apache.cxf.transport.servlet.AbstractHTTPServlet.handleRequest(AbstractHTTPServlet.java:301)
at org.apache.cxf.transport.servlet.AbstractHTTPServlet.doPost(AbstractHTTPServlet.java:220)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:707)
...
Я отладил код CXF и получил следующееВыводы:
-
DefaultResourceManager
имеет верхнюю запись ServletContextResourceResolver
, которая была добавлена CXFNonSpringServlet
. - *
ServletContextResourceResolver
использует метод Каталины ApplicationContext.getResource(String path)
который, в свою очередь, ожидает, что path
начнется с /
.Он добавляет эту косую черту и добавляет StandardRoot.validate()
перечисленное выше исключение. - Это исключение проходит
DefaultResourceManager
и перехватывается методом EndpointReferenceUtils.createSchema()
.Т.е. ни один из других ResourceResolver
объектов (особенно ClasspathResolver
), перечисленных в DefaultResourceManager
, используется для загрузки XSD из пути к классам.
Как мне добиться получения XSDпроверка работает?Есть ли способ изменить порядок ResourceResolver
s?
Отредактировано
- Класс
EndpointReferenceUtils.SchemaLSResourceResolver
разрешает URL-адрес очень хорошо (т.е.newId
содержит требуемый URL-адрес соответствующего файла XSD).Однако он не использует его, так как не перехватывает исключение, выданное ResourceManager
. - . Я не хочу использовать абсолютные пути только в качестве обходного пути ошибки распознавателя.С моей точки зрения
ServletContextResourceResolver
должен вернуть null
, если он не может разрешить XSD и не должен выдавать исключение.