XML 当架构文件位于 WAR 时针对 XSD 进行验证

XML validation against XSDs when schema files locate in a WAR

我正在尝试验证 XML 与乘 XSD 模式的对比。

如果我将我的应用程序作为一个简单的 Spring-启动应用程序来执行,那么下面的代码就像一个魅力:

// init
String[] xsdFileNames = ...
Source[] sources = new Source[xsdFileNames.length];

for (int i = 0; i < xsdFileNames.length; i++) {
    InputStream inputStream = Thread.currentThread().getContextClassLoader().getResourceAsStream(xsdFileNames[i]);
    String realPath = getClass().getClassLoader().getResource(xsdFileNames[i]).getFile();

    StreamSource streamSource = new StreamSource(inputStream);
    streamSource.setSystemId(realPath );

    sources[i] = streamSource;
}

SchemaFactory schemaFactory = SchemaFactory.newInstance(XMLConstants.W3C_XML_SCHEMA_NS_URI);
Schema schema = schemaFactory.newSchema(sources);
validator = schema.newValidator();

// validate
String xmlString = ...
StringReader xmlStringReader = new StringReader(xmlString))
Source source = new StreamSource(xmlStringReader);
validator.validate(source);

需要设置StreamSourcesystemId否则SAXParser看不到来自第二个XSD的XSD类型。更多信息 .

但不幸的是,我的 WAR 需要在 Oracle WebLogic Server 中 运行,并且因为 WebLogic 对来自 WAR 的文件进行了欺骗,所以上面的解决方案不起作用。

WebLogic 将资源文件打包到 _wl_cls_gen.jar 中,并且 javax.xml.transform.Source 无法用这个神奇的 jar 解析路径:.../_wl_cls_gen.jar!/schema/main.xsd.

javax.xml.transform.Source 里面有一个 java.io.File 并且它没有遵循这条奇怪的路径。

这是 realPath 变量在 Spring-Boot:

情况下的值
/home/xxx/dev/workspace/java/xxx/target/classes/schema/main.xsd

对于 WebLogic:

/u01/oracle/user_projects/domains/DEV_DOMAIN/servers/ADMIN_SERVER/tmp/_WL_user/demo-0.1.0/g369dl/war/WEB-INF/lib/_wl_cls_gen.jar!/schema/main.xsd

知道如何处理吗?

您可以使用类加载器从 *.war 中加载文件,例如

getClass().getClassLoader().getResourceAsStream("/resources/myfile.xsd");

尝试在 weblogic.xml

中使用 show-archived-real-path-enabled

show-archived-real-path-enabled The show-archived-real-path-enabled element specifies the behavior of getRealPath() for archived Web applications.

When set to true, getRealPath() returns the canonical path of the resource files.

If the show-archived-real-path-enabled element is set to false, the servlet container will return the real path of files in archived Web applications as null.

The default value is false.

https://docs.oracle.com/cd/E24329_01/web.1211/e21049/weblogic_xml.htm#WBAPP611