【问题标题】:servlets - choose a filename for uploaded filesservlets - 为上传的文件选择一个文件名
【发布时间】:2013-11-02 12:14:00
【问题描述】:

我对图像感兴趣,但问题很笼统。我正在做thusly

private static final SecureRandom RANDOM = new SecureRandom();
private static final int FILENAMElENGTH = 73; // a guess
private static String nextId() { // synchronized ?
    return new BigInteger(FILENAMElENGTH, RANDOM).toString(32);
} // https://stackoverflow.com/a/41156/281545

问题:

  • 使用会话 id + 时间戳存储文件有优缺点吗? 稍后使用此信息中的优点和 安全性中的缺点
  • 是否有任何标准(参见 servlet API 或 Java)生成名称的方法?有什么标准做法吗?任何容器特定提示(glassfish 和 tomcat)

我了解保留原始文件名、用户名等可能会导致安全漏洞

相关:

【问题讨论】:

  • 这完全取决于您对这些名称所做的工作。如果您将图像公开并包含用户的会话 ID,那么显然任何人都可以获取另一个用户的会话 ID 并冒充他。您可以简单地使用数据库序列,和/或对文件内容进行散列以生成唯一名称。随机也很好,除了它是随机的,因此不能提供唯一性的有力保证。
  • @JBNizet:有什么标准做法吗?像 api 中的方法?什么是 db 序列 ?我的用途是保存图片,然后通过 <img src="${sessionScope.photo.path}" /> 事物显示它(确实显示会话 - 哎呀!)
  • 一个 db 序列是一个数据库序列。数据库序列就像一个计数器,但它是持久的,可以由多个线程甚至应用程序共享,并且即使您关闭并重新启动应用程序,也会在最后一个值处重新启动。您向数据库询问下一个值,它会返回它。它通常用于生成主键值。不,没有单一的标准做法可以做你想做的事。
  • @JBNizet:您能否发布一些代码来获取这样的序列 - 比如说 JDBC/MySQL(在答案中:)
  • 不幸的是,MySQL 没有序列。不过,您可以使用 auto_increment 列来模拟它们。 Google 是你的朋友:“MySQL 序列”。

标签: servlets file-upload tomcat7 glassfish-3 servlet-3.0


【解决方案1】:
static File getImageFile() throws IOException {
    return File.createTempFile("upload_", ".jpg", new File(upload_path));
}

// String filename = getImageFile().getName(); 

保证是唯一的 (docs) - 它根本不是 tmp 文件(前提是您可以控制 upload_path,它必须是现有目录的路径(尽管文档不是明确说明))。

显然您应该有更好的方法来指定扩展名,但这是另一个问题。

没有会话 ID、用户输入等

从 BalusC 博客 post 中得到这个想法:

还需要知道 MultipartMap 中的文件上传位置,因为我们可以使用 File#createTempFile() 创建具有唯一文件名的文件,以避免它们被另一个文件覆盖(巧合) 一样的名字。在 servlet 或 bean 中获得上传的文件后,您可以随时使用 File#renameTo() 进行快速重命名/移动。

请注意,在 Java 6.11 之前,createTempFile 曾经相当不安全(请参阅 here 了解说明,here 了解有关 tmp 文件安全性的一般说明)。另请参阅此 SO question - 在文件创建和打开之间存在漏洞窗口。然而,这些问题与文件名无关 - 仍然 createTempFile 是保证唯一性的唯一方法(我希望您使用最新的 JDK,以避免可预测的文件名 createTempFile 遭受)。

【讨论】:

    【解决方案2】:

    您可能想使用Universally Unique Identifier。他们很好supported in Java 7。如果你使用静态方法UUID.randomUUID(),你应该有一个合理的唯一标识符。请注意,理论上您可能会遇到重复项,但这种可能性非常小,以至于它被认为是您尝试做的非常强大的解决方案(请参阅维基百科链接上的讨论)。

    请注意,生成的字符序列根本不是用户友好的,但根据我对您的要求的理解,没关系。

    祝你好运!

    【讨论】:

      猜你喜欢
      • 2018-11-15
      • 2010-11-17
      • 2020-08-01
      • 1970-01-01
      • 1970-01-01
      • 2011-03-24
      • 1970-01-01
      • 2021-10-31
      • 2014-12-10
      相关资源
      最近更新 更多