web-dev-qa-db-ja.com

アプリのresource / imagesフォルダーにファイルを書き込む方法は?

画像をアップロードしてサーバーに保存し、後でh:graphicImageで表示したいですか?アプリの「リソース/画像」に保存したいのですが。 Glassfish 4を使用しています。現在、ファイルは「domain1\generate\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>

私の豆

@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());

    }
}
11
Pavel

アプリの「リソース/画像」に保存したい

いいえ、しないでください。 WAR展開スペースは、永続的なファイル保管場所として意図されていません。これらのアップロードされたファイルはすべて、元のWARに含まれていないという非常に単純な理由で、Webアプリを再デプロイするたびに失われます。非常に密接に関連する質問についての詳細な説明については、この回答も参照してください: アップロードされた画像はページを更新した後にのみ利用可能


現在、ファイルは「domain1\generate\jsp\FileUpload」に移動します。

Part#write()で相対パスを指定したためです。これは、制御できない現在の作業ディレクトリを基準にして行われます。詳細な説明については、この関連する回答も参照してください: getResourceAsStream()vs FileInputStream 。絶対パスを指定する必要があります。つまり、パスを/で開始します。


Glassfishを使用していることを考えると、 アップロードされた画像はページを更新した後にのみ利用可能 の答えもあなたのためにそれを行うはずです。手短に:

  1. /var/webapp/imagesフォルダーを作成します。このパスは単なる例であり、完全に自由に選択できることに注意してください。また、C:\ディスクでWindowsを使用している場合、このパスはC:\var\webapp\imagesと同等であることに注意してください。

  2. アップロードしたファイルをそこに保存します。

    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()は一意のファイル名を自動生成するために使用されています。そうしないと、新しくアップロードされたファイルが(偶然に)まったく同じファイル名である場合、以前にアップロードされたファイルが上書きされます。 )

  3. 次のエントリをwebappの/var/webapp/imagesに追加して、すべてのファイルがhttp://example.com/imagesで利用できるように、/WEB-INF/glassfish-web.xmlに仮想ホストを登録するようにGlassFishに指示します。

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

    (注:alternatedocroot_1はそのようにする必要があります。変更しないでください。複数ある場合は、alternatedocroot_2などの名前を付けてください。また、/imagesの部分は実際にはdir属性、これはタイプミスではありません)

  4. これで、次のように表示できます。

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

    (注:value属性ではなく、name属性を使用してください)

24
BalusC

Glassfishの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;
    }
2
Dapope