我对图片感兴趣,但问题很普遍。我正在做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
问题:
我知道保留原始文件名,用户名等会导致安全漏洞
相关:
答案 0 :(得分:2)
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()进行快速重命名/移动。
请注意createTempFile
在Java 6.11之前曾经相当不安全(参见here获取博览会,here获得tmp文件安全性的一般说明)。另请参阅此SO question - 文件创建和打开之间存在一个漏洞窗口。然而,这些问题与文件名无关 - 仍然createTempFile
是保证唯一性的唯一方法(我希望您使用最新的JDK,以避免受到可预测的文件名createTempFile
)。
答案 1 :(得分:0)
您可能想要使用Universally Unique Identifier。他们很好supported in Java 7。如果使用静态方法UUID.randomUUID()
,则应该具有合理唯一的标识符。请注意,从理论上讲,你可能会遇到重复,但是它的可能性非常小,以至于它被认为是你正在尝试做的非常强大的解决方案(参见维基百科链接上的讨论)。
请注意,生成的字符序列根本不是用户友好的,但根据我对您的要求的理解,这是可以的。
祝你好运!