Domanda

Ho sviluppato un'applicazione Web Java EE. Questa applicazione consente agli utenti di caricare un file con l'aiuto di un browser. Una volta che l'utente ha caricato il suo fascicolo, questa applicazione primi negozi il file caricato sul server (su cui è in esecuzione) e quindi lo elabora.

Al momento, sto memorizzare il file sul server come segue:

try {
    // formFile represents the uploaded file
    FormFile formFile = programForm.getTheFile();
    String path = getServlet().getServletContext().getRealPath("") + "/"
        + formFile.getFileName();
    System.out.println(path);
    file = new File(path);
    outputStream = new FileOutputStream(file);
    outputStream.write(formFile.getFileData());
}

dove, il formFile rappresenta il file inserito.

Ora, il problema è che è in esecuzione bene su alcuni server, ma su alcuni server della getServlet().getServletContext().getRealPath("") sta tornando null in modo che il percorso finale che sto ottenendo è null/filename e il file non memorizza sul server.

Quando ho controllato le API per ServletContext.getRealPath() metodo, ho trovato il seguente:

  

public java.lang.String getRealPath(java.lang.String path)

     

restituisce una stringa contenente il percorso vero e proprio per un determinato percorso virtuale. Ad esempio, il percorso "/index.html" restituisce il percorso di file assoluto sul filesystem del server sarebbe servita da una richiesta di "http://host/contextPath/index.html", dove contextPath è il percorso del contesto di questa ServletContext.

     

Il vero percorso restituito sarà in una forma appropriata per il computer e sistema operativo sul quale il contenitore servlet è in esecuzione, inclusi i separatori di percorso corretto. Questo metodo restituisce null se il contenitore servlet non può tradurre il percorso virtuale in un percorso vero per qualsiasi ragione (ad esempio quando il contenuto viene reso disponibile da un archivio .war).

Quindi, c'è un altro modo con il quale è possibile memorizzare i file su tali server anche che sta tornando null per getServlet().getServletContext().getRealPath("")

È stato utile?

Soluzione

La scrittura del file system da un container Java EE non è davvero consigliato, soprattutto se avete bisogno di elaborare i dati scritti:

  • non è transazionale
  • danneggia la portabilità (cosa succede se ci si trova in un ambiente di cluster)
  • si richiede di parametri esterni di impostazione per il percorso di destinazione

Se questa è un'opzione, vorrei memorizzare i file nella banca dati o utilizzare un repository JCR (come Jackrabbit ).

Altri suggerimenti

Per spec, l'unica strada "reale" si sono garantiti per ottenere formare un servlet container è una directory temp.

È possibile ottenere che attraverso il ServletContext.gerAttribute("javax.servlet.context.tempdir"). Tuttavia, questi file non sono visibili al contesto web (vale a dire non si può pubblicare un semplice URL per fornire tali file), ei file non sono garantiti in alcun modo per sopravvivere ad un'applicazione web o un server di riavvio.

Se avete semplicemente bisogno di un posto per memorizzare un file di lavoro per un breve periodo, quindi questo lavoro bene volontà per voi.

Se si ha realmente bisogno di una directory, si può rendere un parametro di configurazione (o una variabile d'ambiente, una proprietà Java (cioè java -Dyour.file.here=/tmp/files ...), un set di parametri di contesto nel web.xml, un parametro di configurazione memorizzate nel database tramite un modulo web, etc.). Poi tocca al programma di distribuzione per impostare questa directory per voi.

Tuttavia, se avete bisogno di realtà poi servire quel file, vi sia bisogno di un meccanismo contenitore specifico per "montare" le directory esterne al vostro web app (Glassfish come "radici doc alternativo", altri hanno concetti simili), o hai bisogno di scrivere un servlet / filtro per servire fino archivio di file al di fuori della vostra web app. Questo FileServlet è abbastanza completo, e come si può vedi, creando il proprio, mentre non è difficile, non è banale per farlo bene.

Modifica

La sostanza di base è la stessa, ma invece di usare "getRealPath", è sufficiente utilizzare "getInitParameter".

String filePath = getServletContext().getInitParameter("storedFilePath") + "/" + fileName;

e di essere sulla buona strada.

Modifica di nuovo:

Per quanto riguarda il contenuto del percorso, darei un percorso assoluto. In caso contrario, si avrebbe bisogno di sapere dove il server di applicazione imposta il suo percorso predefinito durante exeuction, e ciascun server app può anche utilizzare diverse directory. Per esempio, credo che la directory di lavoro per Glassfish è la directory di configurazione del dominio di esecuzione. Non una scelta particolarmente evidente.

Quindi, utilizzare un percorso assoluto, sicuramente. In questo modo si sa dove i file andranno, ed è possibile controllare le autorizzazioni di accesso a livello di sistema operativo per quella directory, se è necessario.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top