Сервлеты - выберите имя файла для загруженных файлов

Меня интересуют изображения, но вопрос довольно общий. Я делаю это таким образом:

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);
} // /info/934/how-to-generate-a-random-alpha-numeric-string/14419#14419

Вопросы:

  • Есть ли плюсы и минусы при хранении файлов с идентификатором сеанса + меткой времени? Плюсы, как использовать эту информацию позже и минусы, как в безопасности
  • Есть ли какой-либо стандарт (см. сервлет API или Java) способ генерации имени? Любая стандартная практика? Контейнерные кончики (стеклянная рыба и кошка)

Я понимаю, что сохранение исходного имени файла, имя пользователя и т.д. может привести к ошибкам в безопасности.

Связанный:

Ответ 1

static File getImageFile() throws IOException {
    return File.createTempFile("upload_", ".jpg", new File(upload_path));
}

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

Это гарантированно будет уникальным (docs) - и это вовсе не файл tmp (если у вас есть контроль над upload_path, который должен быть путем к существующему каталогу (хотя документы не являются явно об этом)).

Очевидно, что у вас должен быть лучший способ указать расширение, но это еще один вопрос.

Нет идентификаторов сеанса, ввода пользователя и т.д.

Получил идею из блога BalusC post:

Необходимо также знать местоположение загрузки файла в MultipartMap, потому что мы можем использовать File # createTempFile() для создания файлов с уникальным именем файла, чтобы избежать их перезаписывания другим файлом с помощью (по совпадению ) то же имя. После того, как вы загрузили файл в сервлете или bean, вы всегда можете использовать File # renameTo() для быстрого переименования/перемещения.

Обратите внимание, что createTempFile раньше был небезопасным перед Java 6.11 (см. здесь для экспозиции и здесь для общего изложения защиты файлов tmp). Также см. Это SO question - есть окно уязвимости между созданием и открытием файла. Однако эти проблемы не имеют ничего общего с именами файлов. Тем не менее createTempFile - единственный способ гарантировать уникальность (надеюсь, вы используете последний JDK, чтобы избежать постраничных имен файлов createTempFile).

Ответ 2

Вы можете использовать Универсальный уникальный идентификатор. Они красиво поддерживаются в Java 7. Если вы используете статический метод UUID.randomUUID(), у вас должен быть достаточно уникальный идентификатор. Обратите внимание, что в теории вы можете столкнуться с дубликатом, но шансы на это очень малы, настолько, что это считается очень сильным решением для того, что вы пытаетесь сделать (см. Обсуждение ссылки в Википедии).

Помните, что сгенерированная последовательность символов не является удобной для пользователя, но из того, что я понимаю из ваших требований, все в порядке.

Удачи!