如何在Spring中将文件I / O导出为WAR文件

时间:2014-02-11 16:20:48

标签: java spring tomcat file-io war

我需要为Spring应用程序提供一些特殊的文件类型,因此我提出了如何在我的本地计算机上执行万无一失的文件I / O以及将WAR文件上传到服务器。

我自己做了一些研究,发现了一些有用的文章:


到目前为止我尝试了什么

根据DwB的回答,我尝试在我的ServletContext图层中使用Service技术,因为这是需要的地方(内部计算不适合ControllerDAO)。我放下了以下内容:

private String myFile = null;

protected void init(final ServletConfig config) {
    ServletContext context = config.getServletContext();
    String contextPath = context.getContextPath();
    myFile = contextPath + "resources/test.txt";
}

protected void doGet() {
    try {
        BufferedWriter writer = new BufferedWriter(new FileWriter(myFile));
        writer.append("Lorem ipsum dolor sit amet");
        writer.close();
        writer.flush();
    } catch (IOException e) {
        e.printStackTrace();
    }
}

我在其中一个函数中调用了doGet(),但它返回了

THE TIME org.apache.catalina.core.StandardWrapperValve invoke
SEVERE: Servlet.service() for servlet [spring] in context with path [/bosom] threw exception [Request processing failed; nested exception is java.lang.NullPointerException] with root cause
java.lang.NullPointerException

为什么下面的代码不起作用?

  • 简单写作

    BufferedWriter bw = new BufferedWriter(new FileWriter("/src/resources/test.txt"));
    bw.append("Lorem ipsum dolor sit amet");
    bw.close();
    bw.flush();
    
  • InputStreamBufferedReader合作,但现在我迷失了BufferedWriterOutputStreamsource

    InputStream is = getClass().getResourceAsStream("/test.txt");
    BufferedWriter bw = new BufferedWriter(new FileWriter(is));
    bw.append("Lorem ipsum dolor sit amet");
    bw.close();
    bw.flush();
    
  • Spring的Resource也没有帮助(source)。

    我尝试过使用resource.toString()resource.getURI()resource.getURI().toString()resource.getURL()resource.getURL().toString(),但仍然存在错误和错误。

    Resource resource = new ClassPathResource("/src/resources/test.txt");
    BufferedWriter bw = new BufferedWriter(new FileWriter(new File(resource.toString())));
    bw.append("Lorem ipsum dolor sit amet");
    bw.close();
    bw.flush();
    

    它只会返回:

    java.io.FileNotFoundException: class path resource [src\resources\test.txt] (The system cannot find the path specified)
    
    java.io.FileNotFoundException: class path resource [src/resources/test.txt] cannot be resolved to URL because it does not exist
    
    java.io.FileNotFoundException: class path resource [src/resources/test.txt] cannot be resolved to URL because it does not exist
    
  • 我在ENVIRONMENT_VARIABLE中创建了Control Panel >> System >> Environment Variables并创建了myData D:/resources,但是下面的代码没有写任何文件(尽管没有错误) )。

    File file = new File(System.getenv("myData"), "test.txt");
    try {
        BufferedWriter bw = new BufferedWriter(new FileWriter(file.getAbsolutePath()));
        bw.write("Lorem ipsum dolor sit amet");
    
        bw.flush();
        bw.close();
    } catch (IOException e) {
        e.printStackTrace();
    }
    

  

根据当前答案更新

现在我因为这些而有更多的疑问和怀疑而不是答案。请注意,我打算为导出为WAR文件的项目执行文件I / O.

  1. 当项目位于本地计算机和服务器(WAR文件)中时,是否可以成功执行文件I / O?

      

    根据答案,

  2. 如果可能,在哪个文件夹中放置这些特定文件的最理想位置?

      

    没有提到特定的文件夹

  3. 我应该使用哪些实际函数来读写这些文件?

      

    ???

  4. 这是我的Spring应用程序的结构,如Eclipse Workspace中的Windows资源管理器中所示(请注意):

    root
    |----> .settings
    |----> build
    |----> src
    |--------> package.name
    |--------> resources
    |------------> THE_FILES
    |----> WebContent
    |----> .classpath
    |----> .project
    
      

    请注意,我还需要StringInputStream形式的绝对文件路径,因为我使用的是weka.core.SerializationHelper's read method

    我只想拥有一个可靠的文件I / O,它在我的本地机器上工作,甚至在服务器上作为WAR文件上传时(我觉得可能)。

2 个答案:

答案 0 :(得分:0)

您需要的关键信息是“我在哪里写和/或读取文件”。

一种简单的技术是拥有一个环境变量(可能名为MY_FILE_LOCATION),其中包含将包含您关注的文件的目录。这假设您关注的文件不是WAR文件的一部分。

另一种技术是在CLASSPATH中包含一个包含所需位置信息的配置文件(xml或属性)(可能是my.directory = / blam / hoot)。

你可以读取和写入在战争中分发的文件,但似乎war文件在部署时会爆炸,所以IO应该没有问题,只是找到文件的问题。 servletContext有一个方法“getContextPath()”,它将返回当前上下文根的路径。您可以使用它来查找文件。

编辑:我将如何使用Servletcontext。

在我的servlet中,我会做这样的事情:

private String blammoFileName;

protected void init(final ServletConfig config)
{
    ServletContext context = config.getServletContext();
    String contextPath;

    contextPath = context.getContextPath();
    blammoFileName = contextPath + "/path/to/file.txt";
}

protected void doGet(
    final HttpServletRequest request,
    final HttpServletResponse response)
{
    BufferedWriter writer = new BufferedWriter(new FileWriter(blammoFileName));

    ... use writer.
}

答案 1 :(得分:0)

看起来你混淆了几个问题/答案。

这是基础知识。

假设文件是​​静态的,即在构建WAR时将其添加到WAR中,则:

  • 如果您的代码使用了该文件,那么它只需要在类路径中,这在WAR中表示WEB-INF/classesWEB-INF/lib中的JAR。
  • 如果该文件是通过http使用的,那么它需要位于WAR的根目录或其子目录中(显然不是WEB-INF)。

在这两种情况下都不需要展开WAR以使应用程序使用该文件。

但是,如果文件是动态的,即它是由应用程序在运行时创建的,那么您需要创建一个与Tomcat分开的目录,并使用enivornment变量或类似变量引用它。如果该文件也可以通过http获得,那么您需要编写一个servlet,将文件内容写入http响应,设置适当的内容类型。

编辑 - 基于以下评论

有几种设置环境变量的方法,你可以Google

绝对路径是相对于文件系统根目录的相对路径,而不是您碰巧所在的目录。在Unix上,您希望看到它以'/'开头,或者在Windows上以驱动器号{{1}开头例如。

在你的情况下,环境变量应该设置为类似C:\的东西,可以使用/usr/myapp在Java中读取,导致代码如下:

System.getenv

接下来,您询问如何将文件放入File file = new File(System.getenv("MY_ENVIRONMENT_VARIABLE"), "MY_FILE"); - WEB-INF/lib中唯一应该是JAR的内容。正如我之前所说,静态文件(取决于它们的使用方式)应该位于WEB-INF/lib或WAR的根目录或WEB-INF/classes以外的子目录中。例如,属性文件应位于WEB-INF中,而应用程序中使用的图像应位于WAR的根目录或某个子目录中,对于图像可能为WEB-INF/classes