Glassfish - загрузка изображений - это правильно

Я нахожусь на последней стеклянной рыбке (3.1.2) - поэтому нет необходимости в apache FileItem и никаких ошибок с getPart(). Я прочитал, что наилучшая практика загрузки изображений - это сохранение их в файловой системе (например, здесь здесь). Я редактирую уже существующий код - вонючий в этом - так что у меня была идея:

Part p1 = request.getPart("file");
System.out.println("!!!!!P1 : " + p1);

Отпечатки:

!!!!!P1 : File name=DSC03660.JPG, 
StoreLocation=C:\_\glassfish3\glassfish\domains\domain1\generated\jsp\elkethe\upload_7cb06306_138b413999a__7ffa_00000000.tmp, 
size=2589152bytes, isFormField=false, FieldName=file

newlines мой. В коде люди делают:

if (request.getParameter("crop") != null) {
    // get path on the server
    String outputpath = this.getServletContext().getRealPath(
            "images/temp/" + session.getId() + ".jpg");
    // store photo
    InputStream is = p1.getInputStream();
    createPhoto(is, outputpath);
    session.setAttribute("photo_path", "images/temp/" + session.getId()
            + ".jpg");
    response.sendRedirect("cropping");
    return;
}

Где

private void createPhoto(InputStream is, String outputpath) {
    FileOutputStream os = null;
    try {
        os = new FileOutputStream(outputpath);
        // write bytes taken from uploaded file to target file
        int ch = is.read();
        while (ch != -1) {
            os.write(ch);
            ch = is.read();
        }
    } catch (Exception ex) {
        ex.printStackTrace();
    } finally {
        Helpers.close(os);
    }
}

Теперь случается, что файл загружается в StoreLocation (???) при отправке формы, поэтому, очевидно, все это p1.getInputStream() ничто.

Мои вопросы:

  • Что такое StoreLocation? Как tmp загружаются в эти стеклянные рыбы? Где все эти параметры установлены? Я прочитал инструкцию BalusC , но нет упоминания о StoreLocation (google не очень полезно либо).
  • Что было бы более профессиональным способом справиться с ситуацией - в том числе с сохранением фотографий за пределами веб-сайта, - но с использованием средств, предоставляемых сайгаком (если это предусмотрено)?
  • Даже печать p1 так хорошо меня убеждает (это не показаться для переопределения toString())

Заинтересованы в советах даже в том, как следует переименовывать фотографии и т.д. (эта вещь SessionID Right? - проверьте также трюк времени):

if (request.getParameter("save") != null) {
    long time = System.currentTimeMillis();
    String path = "images/upload/" + session.getId() + time + ".jpg";
    String outputpath = this.getServletContext().getRealPath(path);
    // store photo
    InputStream is = p1.getInputStream();
    createPhoto(is, outputpath);
    // etc
}

Ответы

Ответ 1

Что такое StoreLocation? Как tmp загружаются в эти стеклянные рыбы? Где все эти параметры установлены?

StoreLocation - это только объект java.io.File для FileItem.  временное местоположение данных на диске. Оставляет в javax.servlet.context.tempdir значение по умолчанию %GLASSFISH_HOME%\domains\domain1\generated\jsp\webApp. Эти загрузки как tmp как что-либо (время жизни файла привязано к времени жизни экземпляра FileItem, файл будет удален, если экземпляр собран из мусора - из здесь). Пока еще не удалось изменить значение javax.servlet.context.tempdir программно (прокомментируйте пожалуйста) - это свойство tempdir элемента sun-web-app sun-web.xml.

Что было бы более профессиональным способом справиться с ситуацией - в том числе с сохранением фотографий за пределами веб-сайта, - но с использованием средств, предоставляемых сайгаком (если это предусмотрено)?

Ну, более профессиональным способом является использование Part.write() для перемещения файла в нужное место. Из-за реализации стеклянной рыбы, хотя вы не можете предоставить абсолютный путь для написания - хлопот. Я спросил здесь.

Что касается сохранения файла: fooobar.com/questions/4465/...

То есть для сохранения файла - для его обслуживания из местоположения вне приложения, вам необходимо определить свойства "alternatedocroot" в sun-web.xml(или glassfish-web.xml).

Даже печать p1 настолько приятна, что меня убегает (это не похоже на переопределение toString())

О да он делает

Заинтересованы в советах даже в том, как следует переименовывать фотографии и т.д. (эта вещь SessionID Right? - проверьте также трюк времени)

Нет, это не так. Я склоняюсь к File#createTempFile() - так или иначе, это другой вопрос, заданный здесь

Ответ 2

Хорошей практикой является выбор пути в файловой системе, где будут загружены фотографии. Часто этот путь запрограммирован для конфигурирования с помощью java-системного свойства (например: путем передачи -Dcom.mycompany.uploadPath=/path/to/photos/dir системного свойства на аргументы JVM).

Вы также можете использовать java-системы для поиска пути к конкретной среде: user.dir, user.home и т.д. См. Свойства системы в учебнике Java SE. Или использовать относительный путь, связанный с морской поверхностью, см. свойства системы стекловолокна.

Как только вы ссылаетесь на Part, он просто делает файл IO для копирования загруженного файла в этот путь загрузки, например:

Part part = // obtain part somehow..
String photoFileName = // build a file name somehow..
InputStream photoInputStream = part.getInputStream();
FileOutputStream photoOutputStream = new FileOutputStream(System.getProperty("com.mycompany.uploadPath") + File.separator + photoFileName);
IOUtils.copy(photoInputStream, photoOutputStream);
// close streams here...

В коде выше используется apache IOUtils для удобства, но не стесняйтесь писать свой собственный метод копирования. Вы также должны добавить метод обработки исключений