在Java Struts应用程序中放置在何处以及如何调用本地XSD文件?
我正在编写一个JavaStruts应用程序,它根据本地存储的XSD文件验证传入的XML文件。我遇到了两个问题:在Java Struts应用程序中放置在何处以及如何调用本地XSD文件?,java,xml,xsd,struts,Java,Xml,Xsd,Struts,我正在编写一个JavaStruts应用程序,它根据本地存储的XSD文件验证传入的XML文件。我遇到了两个问题: XSD文件需要存储在本地,即不通过http调用。我应该在Struts应用程序的哪个位置存储XSD文件?例如,它应该进入WEB-INF吗?我需要把它放在我的src包中吗?我已经看过很多关于本地存储的XSD的内容,但是没有任何特定于Struts的内容 存储后,如何从Java代码引用这个XSD文件?我不知道如何告诉我的程序在哪里找到文件 换言之,我所拥有的是: SchemaFactory s
SchemaFactory schemaFactory = SchemaFactory.newInstance(XMLConstants.W3C_XML_SCHEMA_NS_URI);
Schema schema = schemaFactory.newSchema(new File("/path/to/schema.xsd"));
我不知道/path/to/schema.xsd
应该是什么样子
我在这个论坛上看过类似的问题,但还是有点迷茫。我非常感谢社区能提供的任何帮助
提前谢谢 因此,在进行了大量额外的研究之后,我了解到我受到了Java反射和Struts上下文知识缺乏的阻碍。见鬼,我甚至不知道什么是“资源” 我已经解决了这个问题,但当我朝着一个解决方案前进时,我写了下面的教程来帮助我跟踪我正在学习的新概念。希望这能帮助下一个遇到这个问题并需要更明确细节的人。请让我知道,如果有什么我没有说清楚或如果我误解了一个概念,我会纠正和澄清 首先,让我们从一个资源开始。我了解到,在Java上下文中,“资源”是与应用程序相关的任何文件或数据片段,而不是Java代码。例如,这可能是一个文本或图像文件,或者在我的例子中是一个XSD文件 现在,为了获得资源,我们必须告诉Java程序在哪里可以找到它。这意味着我们需要资源的完整(绝对)文件路径。对于普通Java项目,获取此文件路径的一种方法是
this.getClass().getResource("file.txt");
其中file.txt
是我们要查找的文件名。这将返回一个URL对象,这是一种特殊类型的Java对象,保存文件路径或URL。我们可以调用对象的toString()
方法来获取完整的URL。因此,下面的代码块
URL thisFile1 = this.getClass().getResource("resource.txt");
System.out.println(thisFile1.toString());
打印以下内容:
file:/C:/path/to/workspace/folder/bin/sandbox/test/pkg1/resource.txt
但是,只有当resource.txt与进行上述调用的源代码(在本例中是,sandbox.test.pkg1
)位于同一个包中时,才会出现这种情况
这是因为getResource()
假定其输入参数是相对文件路径,除非文件路径以“/”开头。如果是这样,getResource()
将输入参数视为绝对文件路径,其中根目录是编译后的代码目录,即包层次结构的顶部(“bin”文件夹)。换句话说,这两行代码将产生相同的结果:
URL thisFile1 = this.getClass().getResource("resource.txt");
URL thisFile1 = this.getClass().getResource("/sandbox/test/pkg1/resource.txt");
不太明显的是,为什么我们必须先调用getClass()
,然后才能调用getResource()
。我想知道为什么我们需要调用getClass()
。将getResource()
作为对象方法不是更容易吗?这似乎是一个混乱和不必要的步骤
嗯,getClass()
返回Java类对象的实例,这是一个特殊的Java对象,返回有关Java类的信息。换句话说,以这段代码为例:
public class myClass
{
public void myMethod()
{
Class thisClass = this.getClass();
}
public void method2() {...}
public void method3() {...}
}
如果我们调用myMethod()
,我们会得到一个类的实例,其中包含关于myClass对象的信息。例如,如果我们打电话
Method[] theseMethods = thisClass.getMethods();
我们得到myClass中所有方法的数组(myMethod()
,method2()
,method3()
,等等)。这是Java反射,它有多种用途,因为我们可以在程序运行时收集和检查Java类的属性
那么,如果我们获得了外部资源,我们为什么要关心这一点呢?因为要获取资源,我们首先需要获取关于想要获取资源的类的信息
让我们回到前面的示例:
URL thisFile1 = this.getClass().getResource("resource.txt");
这将在当前目录中搜索文件“resource.txt”,但getResource()
不会自动知道当前目录是什么。它需要获取调用它的类的信息,以知道要搜索哪个目录。Class对象只包含这种信息,这就是为什么getResource()
是Class对象而不是object对象的方法
到目前为止,一切顺利。但是,当我们试图从本地Tomcat服务器上运行的JavaStruts应用程序中获取资源时,而不是从传统的Java项目中获取资源时,事情就变得复杂了。使用Struts和Tomcat,文件最终位于一个非常不同的位置:
URL thisFile1 = this.getClass().getResource("resource.txt");
System.out.println(thisFile1.toString());
产生
file:/C:/path/to/Tomcat/server/folder/.metadata/.me_tcat/webapps/ProjectName/WEB-INF/classes/sandbox/test/pkg1/resource.txt
这要复杂得多,也不那么直观。另外,如果我们想要的文件与调用它的源代码不在同一目录中,该怎么办?对于Struts应用程序,通常将资源文件放在其他地方。这是因为Struts建立在分离程序不同部分的原则上,以更好地管理程序流(MVC范式),因此将资源文件与源代码捆绑似乎违反了这一原则(无论如何,我认为)
我想把我的资源文件放到WEB-INF中,但放在“classes”文件夹之外——比如说放在“resources”文件夹中——但这使得getResource()
更加复杂。从getResource()
的角度来看,根目录是
file:/C:/path/to/Tomcat/server/folder/.metadata/.me_tcat/webapps/ProjectName/WEB-INF/classes/
因此,要在文件层次结构中向上移动,我们必须用一个或多个。/
来制定一个复杂的相对路径。这很混乱,很难理解。还有更优雅的方式吗
有
URL thisFile1 = this.getServlet().getServletContext().getResource("/WEB-INF/resources/resource.txt");
这是怎么回事?记住,Struts是一个使用Javaservlet的框架。这意味着我们的源代码在servlet中。这个servlet又是web应用程序的一部分(据我所知,它可以
String xsdFile = "";
SchemaFactory schemaFactory = SchemaFactory.newInstance(XMLConstants.W3C_XML_SCHEMA_NS_URI);
try
{
xsdFile = this.getServlet().getServletContext().getResource("/WEB-INF/resources/schema.xsd").toString();
}
catch (Exception e)
{
return e.getMessage();
}
Schema schema = schemaFactory.newSchema(new File(xsdFile));
file:/C:/Users/user/AppData/Local/MyEclipse%20Professional%202014/plugins/com.genuitec.eclipse.easie.tomcat.myeclipse_11.0.0.me201211151802/tomcat/bin/jndi:/localhost/ProjectName/WEB-INF/resources/schema.xsd
jndi:/localhost/ProjectName/WEB-INF/resources/schema.xsd
URL xsdFile = "";
SchemaFactory schemaFactory = SchemaFactory.newInstance(XMLConstants.W3C_XML_SCHEMA_NS_URI);
try
{
xsdFile = this.getServlet().getServletContext().getResource("/WEB-INF/resources/schema.xsd");
}
catch (Exception e)
{
return e.getMessage();
}
Schema schema = schemaFactory.newSchema(xsdFile);
SchemaFactory schemaFactory = SchemaFactory.newInstance("http://www.w3.org/2001/XMLSchema");
Schema schema = schemaFactory.newSchema(loadXSD());
private static Source loadXSD(){
Source xsd = new StreamSource(Thread.currentThread().getContextClassLoader()
.getResourceAsStream("File stored in src/"));
return xsd;
}