Как записать файл в папку ресурсов/изображений приложения?

Я хотел бы загрузить изображение и сохранить его на сервере, а затем показать его с h: graphicImage? Я хотел бы сохранить его в "resources/images" приложения. Я использую glassfish 4. Прямо сейчас, файл переходит к "domain1\generated\jsp\FileUpload". Спасибо вам

Моя форма

<h:form id="form" enctype="multipart/form-data">
        <h:messages/>
        <h:panelGrid columns="2">
            <h:outputText value="File:"/>
            <h:inputFile id="file" value="#{uploadPage.uploadedFile}"/>
        </h:panelGrid>
        <br/><br/>
        <h:commandButton value="Upload File" action="#{uploadPage.uploadFile}"/>
</h:form>

Мой bean

@Named
@ViewScoped
public class UploadPage {       
    private Part uploadedFile; 

    public void uploadFile(){
       File file = File.createTempFile("somefilename-", ".jpg", new File("C:\\var\\webapp\\images"));
    uploadedFile.write(file.getAbsolutePath());

    }
}

Ответ 1

Я хотел бы сохранить его в "ресурсах/изображениях" приложения

Нет, пожалуйста, не надо. Пространство развертывания WAR не предназначено для постоянного хранения файлов. Все эти загруженные файлы будут потеряны всякий раз, когда вы повторно развертываете webapp по той простой причине, что они не содержатся в исходной WAR. См. Подробное объяснение и ответ на очень близкий вопрос: Загруженное изображение доступно только после обновления страницы.


В настоящий момент файл переходит к "domain1\generated\jsp\FileUpload".

Потому что вы указали относительный путь в Part#write(). Он становится относительно текущего рабочего каталога, который вы не контролируете. См. Подробное объяснение и этот ответ: getResourceAsStream() vs FileInputStream. Вам нужно указать абсолютный путь, другими словами, запустить путь с помощью /.


Учитывая, что вы используете Glassfish, ответ в Загруженном изображении, доступном только после обновления страницы, также должен сделать это за вас. В двух словах:

  • Создайте папку /var/webapp/images. Обратите внимание, что этот путь является просто пробным и полностью бесплатным по вашему выбору. Также обратите внимание, что, когда вы используете Windows с диском C:\, этот путь эквивалентен C:\var\webapp\images.

  • Сохраните загруженный файл там.

    Path file = Files.createTempFile(Paths.get("/var/webapp/images"), "somefilename-", ".jpg", );
    
    try (InputStream input = uploadedFile.getInputStream()) {
        Files.copy(input, file, StandardCopyOption.REPLACE_EXISTING);
    }
    
    imageFileName = file.getFileName().toString();
    // ...
    

    (примечание: Files#createTempFile() используется для автогенерации уникального имени файла, в противном случае ранее загруженный файл будет перезаписан, когда новый загруженный файл (по совпадению) имеет точно такое же имя файла)

  • Скажите GlassFish зарегистрировать виртуальный хост на /var/webapp/images, чтобы все файлы были доступны в http://example.com/images, добавив следующую запись в /WEB-INF/glassfish-web.xml веб-сайта:

    <property name="alternatedocroot_1" value="from=/images/* dir=/var/webapp" />
    

    (примечание: alternatedocroot_1 должно быть точно так же, не изменяйте его, если у вас его несколько, назовите его alternatedocroot_2 и т.д., также обратите внимание, что часть /images не должна быть включена в атрибут dir, это не опечатка)

  • Теперь вы можете отобразить его следующим образом:

    <h:graphicImage value="/images/#{bean.imageFileName}" />
    

    (обратите внимание: используйте атрибут value, а не атрибут name)

Ответ 2

Не удалось заставить его работать с Path#write в стеклянную рыбку, поэтому я использовал Path#getInputStream следующим образом:

public void upload(){
        BufferedInputStream bis = null;
        BufferedOutputStream bos = null;
        try {
            String filename = getFilename(uploadedFile);
            File file = new File("/var/webapp/images/"+filename);
            bis = new BufferedInputStream(uploadedFile.getInputStream());
            FileOutputStream fos = new FileOutputStream(file);
            bos = new BufferedOutputStream(fos);
            int x;
            while((x = bis.read())!= -1){
                bos.write(x);
            }
        } catch (IOException ex) {
            Logger.getLogger(Controller.class.getName()).log(Level.SEVERE, null, ex);
        }
        finally{
            try {
                bos.flush();
                bos.close();
                bis.close();
            } catch (IOException ex) {
                Logger.getLogger(Controller.class.getName()).log(Level.SEVERE, null, ex);
            }
        }
    }

private static String getFilename(Part part) {
        for (String cd : part.getHeader("content-disposition").split(";")) {
            if (cd.trim().startsWith("filename")) {
                String filename = cd.substring(cd.indexOf('=') + 1).trim().replace("\"", "");
                return filename.substring(filename.lastIndexOf('/') + 1).substring(filename.lastIndexOf('\\') + 1); // MSIE fix.
            }
        }
        return null;
    }