Java 访问Tomcat上的本地文件

Java 访问Tomcat上的本地文件,java,tomcat,servlets,Java,Tomcat,Servlets,我使用的是ApacheTomcat7,我有一个servlet,其中列出了目录中的所有文件,并允许用户通过单击链接下载文件 问题是: 我在servlet中访问的文件不在项目目录本身中。它们位于tomcat目录本身之外的目录中 即 项目位于/opt/apache-tomcat-7.0.53中 文件位于/Files中/ 当我使用锚定标记时,我不能使用href=“”引用,因为这假设目录位于项目的WebContent文件夹中 我试过做href=”file:///files/但我无法点击链接下载文件,所以一

我使用的是ApacheTomcat7,我有一个servlet,其中列出了目录中的所有文件,并允许用户通过单击链接下载文件

问题是:

我在servlet中访问的文件不在项目目录本身中。它们位于tomcat目录本身之外的目录中

项目位于/opt/apache-tomcat-7.0.53中 文件位于/Files中/

当我使用锚定标记时,我不能使用href=“”引用,因为这假设目录位于项目的WebContent文件夹中

我试过做
href=”file:///files/
但我无法点击链接下载文件,所以一定是出了问题

有人知道如何解决这个问题吗


编辑:我还应该指出,这不是在我的本地计算机上运行的。这是在服务器上。

Tomcat本身只能提供WebContent目录中的文件,而不能提供WEB-INF中的文件。但是servlet可以访问服务器上的任何文件。 因此,您基本上有两种解决方案:

  • 如果是,则链接WebContent下的外部目录不会导致安全问题,如果Tomcat接受遵循符号链接(假设服务器在类Unix系统(如Linux)下)
  • 或者通过构造一个伪目录列表和服务文件,在WebApplication中明确地进行转换
在第二个解决方案中,您可以在servlet域中选择任意根url,如http:server.domain.org/app/path/to/files。文件目录不必存在于WebContent下,但必须有一个控制器,该控制器响应url,如http:server.domain.org/app/path/to/files/myfile.ext,并直接为外部目录下的同名文件


第二个解决方案要复杂得多,但它提供了对通过应用程序真正可访问内容的最大程度的控制。我认为,只有在您有安全需要或必须进行特殊操作时,才应该使用它。我使用它来完全控制需要上传和下载文件的应用程序相对于业务ess URL。

您应该使用javax.servlet.Filter接口

public class ResourceProxyFilter implements Filter {

    private static final String PROXY_CONTROLLER_PREFIX = "/proxyFilter/";

    @Override
    public void init(FilterConfig config) throws ServletException {
    }

    @Override
    public void destroy() {
    }

    @Override
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain filterChain) throws IOException {
        String requestURI = getRequestURI(request);

        File requestedResource = getRequestedResource(requestURI);
        sendResponse(response, requestedResource);
    }

    private String getRequestURI(ServletRequest request) {
        HttpServletRequest httpRequest = (HttpServletRequest) request;

        return httpRequest.getRequestURI();
    }

    private File getRequestedResource(String requestURI) {
        String requestedResourcePath = requestURI.substring(requestURI.indexOf(PROXY_CONTROLLER_PREFIX) + PROXY_CONTROLLER_PREFIX.length());
        File dirWithYourFiles = new File("/files");

        return new File(dirWithYourFiles, requestedResourcePath);
    }

    private void sendResponse(ServletResponse response, File requestedResource) throws IOException {
        HttpServletResponse httpResponse = (HttpServletResponse) response;
        ServletOutputStream writer = httpResponse.getOutputStream();
        writer.write(ByteStreams.toByteArray(new FileInputStream(requestedResource)));
        writer.flush();
        writer.close();
    }
}
然后,您必须将过滤器添加到web.xml:

<filter>
    <filter-name>resourceProxyFilter</filter-name>
    <filter-class>eu.company.ResourceProxyFilter</filter-class>
</filter>
<filter-mapping>
    <filter-name>resourceProxyFilter</filter-name>
    <url-pattern>/proxyFilter/*</url-pattern>
</filter-mapping>

资源代理过滤器
eu.company.ResourceProxyFilter
资源代理过滤器
/proxyFilter/*

您最好看看。它们允许您将外部目录装载到web应用程序的上下文中,并让Tomcat直接提供该文件

增编:

URL中
前面的部分称为“scheme”。示例包括“http”、“https”、“ftp”以及“file”

方案告诉浏览器如何处理URL的其余部分,不同的方案在
之后可以有不同的格式

因此,以
file://
开头的URL使用“文件”方案。文件方案告诉浏览器尝试打开URL其余部分指定的文件名。该文件名是本地文件名。是浏览器的本地文件名,而不是服务器的本地文件名


您几乎不会在基于服务器的应用程序上使用
文件://
类型的URL,而只能在客户端应用程序上使用。

文件://
在web应用程序中。您是对的,但是@SlashTag首先需要了解
文件://
不起作用的原因。@davidermann我确实理解
文件://
不起作用的原因,谢谢这是一个极好的答案。它以最简单的方式准确地回答了我想要的。此外,额外的信息是有用的知识。标记为最佳答案。