【问题标题】:How to serve dynamically created files with Java spring?如何使用 Java spring 提供动态创建的文件?
【发布时间】:2019-06-03 13:55:41
【问题描述】:

我正在尝试构建一个将生成文件(.js 文件)的应用程序(使用 Spring 启动),这些文件必须是公开可用的。 这些文件(创建后)应该可以通过我服务器上的链接访问,并且可以插入到其他人的网站(带有链接)。 类似于“jQuery”或“Google Adwords”的工作方式(它们如何与 html 脚本标签连接)。 所以我面临的问题(或者只是缺乏知识)是如何动态创建这些文件并让它们公开访问。

一般的想法是:1 个用户有 1 个文件夹(例如在资源/文件文件夹内)(我们将其命名为文件夹 1232)。在此文件夹中生成了他的特定 js 文件(例如 111.js)。所以我希望他能够通过请求 app.com/files/folder1232/111.js URL 来访问他的文件。这样做的方式是什么? 如果有不清楚的地方请告诉我。

我目前正在使用资源文件夹来了解它的一般工作方式。我看到的是文件在启动时以某种方式映射(例如,如果我在运行时创建一个包含文件的新文件夹,则在我重新启动应用程序之前无法访问它)。 我也尝试使用 WebMvcConfigurer,但我认为我缺少一些基本的东西。

@Configuration
@EnableWebMvc
public class MvcConfig implements WebMvcConfigurer {

    @Override
    public void addResourceHandlers(ResourceHandlerRegistry registry) {
        registry.addResourceHandler("/files/**")
                .addResourceLocations("file:/files/")
                .setCachePeriod(3600)
                .resourceChain(true)
                .addResolver(new PathResourceResolver());
    }
}

我希望从浏览器访问新创建的文件(在运行时)。 如果我也能够访问新创建的文件夹(在运行时),那也将是完美的。 但是 atm 我必须重新启动应用程序才能访问新创建的文件和文件夹。

更新: 我接下来尝试做的是在我的 java 项目之外创建一个文件夹。 像这样:/Users/%username%/Documents/fileFold 并将我的 addResourceHandler 函数更改为:

@Override
    public void addResourceHandlers(ResourceHandlerRegistry registry) {
        registry.addResourceHandler("/files/**")
                .addResourceLocations("file:/Users/%username%/Documents/fileFold/")
                .setCachePeriod(0)
                .resourceChain(true)
                .addResolver(new PathResourceResolver());
    }

现在它可以完美运行了。谢谢大家! 注意:不要忘记 addResourceLocations 函数中的最后一个斜杠,没有它映射将无法工作(至少对我不起作用)。

【问题讨论】:

  • 不要将应用中的文件与用户数据混在一起
  • 这是与 stackoverflow.com/questions/46567681/… 重复的接近边缘
  • 您必须重新启动您的应用程序,因为resources 文件夹是您的项目的一部分,它是在您启动它之前构建的。这不是动态生成文件的地方(正如@Jens 指出的那样),尤其不是由用户操作生成的文件。您应该使用项目结构之外的专用文件夹。 Spring Boot 中的默认值是(它认为)您应用程序的当前工作目录,因此如果您 new File("userFiles/folder1232").mkdirs()(或类似的东西),该文件夹将在当前工作目录中创建。
  • 你必须改变你的方法:1。对于真实文件,您应该使用禁用缓存的 nginx 或 apache(Spring boot 并非设计为静态文件服务器),2. 但如果您的文件是通过 java 生成的,请将它们作为普通资源提供,而不是使用 resourceHandler。
  • @pdem 如果我在我的 WebMvcConfigurer 继承者中做 registry.setCachePeriod(0),那还不够吗?

标签: java spring spring-boot spring-mvc model-view-controller


【解决方案1】:

首先, 了解您实际尝试解决的问题。 不要只是跳到“我想要这个解决方案”。

您试图解决的问题似乎是这样的:

  1. 我的应用程序将“创建”一些副本(副本是文本的通用术语,包括您的 .js 文件)。
  2. 所述副本将通过一些唯一标识符公开寻址。

上述要求都不要求您在任何地方创建文件。

一个简单的解决方案是: 在下面的解决方案中,“行”可以是正好一行,也可以是 1 行或多行的有序集合。

  1. 在表中创建包含要提供的“副本”的行。
  2. 使用唯一值来标识行。
  3. [可选] 创建一个表以在行的可读名称(也称为文件名)和所述行的唯一标识符之间进行转换。
  4. 创建一个 REST 服务以通过人类可读的名称获取行。

【讨论】:

    【解决方案2】:

    那么具体对我有用的是: 我创建了一个文件夹来存储项目外部的文件。 例如/Users/%username%/Documents/fileFold

    并将我的 addResourceHandlers 函数更改为

    registry.addResourceHandler("/files/**")
                    .addResourceLocations("file:/Users/%username%/Documents/fileFold/")
                    .setCachePeriod(0)
                    .resourceChain(true)
                    .addResolver(new PathResourceResolver());
    

    注意:不要忘记 addResourceLocations 函数中的最后一个斜杠,没有它映射将无法工作(至少对我不起作用)。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2017-12-05
      • 2013-03-29
      • 1970-01-01
      • 2013-03-06
      • 2017-11-28
      • 1970-01-01
      • 1970-01-01
      • 2018-11-01
      相关资源
      最近更新 更多