【问题标题】:Accessing local files on Tomcat访问 Tomcat 上的本地文件
【发布时间】:2014-05-29 20:43:32
【问题描述】:

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

问题来了:

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

I.E.

项目位于 /opt/apache-tomcat-7.0.53 文件在 /files/

当我使用锚标记时,我无法使用 href="" 进行引用,因为它假定目录位于项目的 WebContent 文件夹中。

我尝试了href="file:///files/<FILE NAME>,但我无法点击链接下载文件,所以一定有问题。

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

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

【问题讨论】:

  • file:// 在网络应用程序中。

标签: java tomcat servlets


【解决方案1】:

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

附录:

: 之前的 URL 部分称为“方案”。示例包括“http”、“https”、“ftp”以及“file”。

scheme 告诉浏览器用 URL 的其余部分“做什么”,不同的scheme 在: 之后可以有不同的格式。

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

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

【讨论】:

  • 你是对的,但@SlashTag 首先需要了解为什么 file:// 不起作用。
  • @DavidEhrmann 我明白为什么 file:// 由于这个答案而无法正常工作。
  • 这是一个很好的答案。它以最简单的方式准确地回答了我想要的。此外,额外的信息是有用的知识。标记为最佳答案。
【解决方案2】:

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

  • 在 WebContent 下链接外部目录如果不会导致安全问题并且如果 Tomcat 接受遵循符号链接(假设服务器在类似 Unix 的系统下,例如 Linux)
  • 通过构造伪目录列表和提供文件在 WebApplication 中显式地进行转换

在第二种解决方案中,您可以在 servlet 域中选择任意根 url,例如 http:server.domain.org/app/path/to/files。文件目录不必存在于 WebContent 下,但您必须有一个控制器来响应 http:server.domain.org/app/path/to/files/myfile.ext 之类的 url,并直接提供外部目录下的同名文件。

第二种解决方案要复杂得多,但可以最大程度地控制可通过应用程序真正访问的内容。恕我直言,您应该仅在您有安全需求或必须进行特殊操作时使用它。我已经使用它来完全控制需要相对于业务 URL 上传和下载文件的应用程序。

【讨论】:

    【解决方案3】:

    你应该使用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>
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2014-08-04
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多