Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/354.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
在Java Struts应用程序中放置在何处以及如何调用本地XSD文件?_Java_Xml_Xsd_Struts - Fatal编程技术网

在Java Struts应用程序中放置在何处以及如何调用本地XSD文件?

在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

我正在编写一个JavaStruts应用程序,它根据本地存储的XSD文件验证传入的XML文件。我遇到了两个问题:

  • XSD文件需要存储在本地,即不通过http调用。我应该在Struts应用程序的哪个位置存储XSD文件?例如,它应该进入WEB-INF吗?我需要把它放在我的src包中吗?我已经看过很多关于本地存储的XSD的内容,但是没有任何特定于Struts的内容

  • 存储后,如何从Java代码引用这个XSD文件?我不知道如何告诉我的程序在哪里找到文件

  • 换言之,我所拥有的是:

    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;
    }