Domanda

Sto scrivendo una semplice applicazione che consente a un utente di upload immagini. Dopo il caricamento, l'utente può loro tag o rimuoverli.

ho capito come caricare i file e salvarli una volta che i file vengono caricati. Sto mantenendo il monitoraggio di un percorso globale in cui sono conservate le immagini. Nel database tengo i meta-dati sulle immagini come nome del file, tag, ecc.

Sto usando Java / JSP (in particolare Stripes quadro, ma il mio problema è generico).

La mia domanda è dove posso mantenere questi file di immagini una volta caricate?

In questo momento ho due applicazioni Web distribuite in un server Tomcat. Uno principale di applicazioni web e un altro è il dove caricare le immagini.

Ma questo non funziona come non riesco a vedere le immagini caricate nel ricorso principale fino a quando ho ridistribuire / riavviare Tomcat.

Sembra che Tomcat non raccoglie immagini appena caricati automaticamente.

Qualcuno ha qualche soluzione?

Questo è un progetto semplice, quindi non voglio per memorizzarli in un database o utilizzare Apache per le immagini. Questo è tutto troppo complicato per questo piccolo progetto.

Grazie.

È stato utile?

Soluzione

Sicuramente non memorizzare le immagini nel database, ma si vuole memorizzare il percorso dell'immagine nel database. Questo vi permetterà di memorizzare l'immagine un po 'ovunque.

Dal momento che si sta utilizzando due applicazioni Tomcat, la soluzione migliore potrebbe essere quella di memorizzare le immagini al di fuori di un'app e lo streaming l'immagine di nuovo per l'utente invece di lasciare Tomcat gestire i file. In caso contrario, vorrei chiedere il motivo per cui si sta cercando di fare questo con due applicazioni web.

Altri suggerimenti

Tuttavia, la memorizzazione di immagini caricate all'interno della directory web-app non è una cosa saggia da fare, e tu lo sai.

A proposito, si potrebbe desiderare di guardare questo StackOverflow filetto , recentemente discusso dove memorizzare le immagini. Potrebbe non risolvere il problema, sicuramente vi darà più fiducia su quello che si sta facendo.

Ho risolto questo in modi diversi.

In primo luogo, il modo in cui non portabile, è che Glassfish (e credo Tomcat pure) consente di mappare una directory esterna per gerarchia webapps. Questo funziona molto bene e fa esattamente quello che vuoi. Esso consente di memorizzare le immagini in una directory esterna lontano dal tuo webapp, ma ancora li servire fino.

Tuttavia, questa tecnica non è portabile.

Il modo per ho fatto portabile è con la creazione di un filtro.

Si posiziona il filtro di un posto ovvio, dire "/ immagini".

Quello che il filtro non è questo:

  • controlla per l'immagine (o qualsiasi cosa, funziona con qualsiasi risorsa statica) in una directory speciale all'interno della webapp. Per il nostro esempio useremo l'URL "/ webapp / immagini".

  • Se il file non esiste, copiamo il file dalla posizione esterna nel punto appropriato all'interno della webapp. Quindi, diciamo che l'url è reqyest "/images/banner.gif". E che i file sono memorizzati su disco in "/ home / app / immagini". Quindi, il nostro file sorgente è "/home/app/images/banner.gif". Abbiamo poi copiarlo dove vogliamo nell'albero webapp. Usiamo "ServletContext.getRealPath" per questo. Quindi, la destinazione sarà "ServletContext.get realpath (" / webapp / images / banner.gif "). Basta copiare il codice sorgente alla destinazione.

  • se il file esiste già, o adesso esiste, semplicemente in avanti per l'immagine reale a /webapp/images/banner.gif.

In effetti si finisce per avere una cache dei file all'interno del vostro albero di distribuzione webapps. Il lato negativo è che si tratta di una cache, quindi ha bisogno di essere mantenuto (vale a dire si dovrebbe verificare se l'originale è più recente la cache, assicurarsi che si elimina se la sorgente viene cancellato, ecc). Inoltre, duplica le risorse, in modo che le immagini si consumano, alla fine, lo spazio su disco due volte tanto. Infine, c'è il costo copia iniziale all'avvio.

Tuttavia, funziona, e ti impedisce di avere a servire risorse statiche utilizzando il proprio codice. (Che è la terza soluzione, la mappa di un filtro / servlet per intercettare gli URL e semplicemente in streaming la vostra auto.)

Vorrei guardare il costrutto all'interno di Tomcat (ammesso che esista) per fare il mapping per voi. So che esiste in Glassfish. (Alternatedocroot Google per Glassfish per vedere come funziona.)

Stavo usando due applicazioni di Internet per evitare di scrivere le immagini caricate nel caso mi ridistribuire un nuovo file di guerra principale dell'applicazione.

Ma come si parla non c'è altra scelta se non per lo streaming di loro attraverso una Servlet o qualcosa credo che posso tenerli directory Tomcat esterno.

Ho voluto evitare di scrivere questo Streaming Servlet. Troppo piccolo progetto a che fare con tutto il casino (come il tipo di contenuto proprio, 404, etc.) durante la scrittura del servlet streaming.

import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.PrintWriter;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

/**
 * Image streaming Servlet.
 */
public class ImageDisplayServlet extends HttpServlet {
    private static final long serialVersionUID = 1L;

    /**
     * @see HttpServlet#HttpServlet()
     */
    public ImageDisplayServlet() {
        super();
    }

    /**
     * @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse response)
     */
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        String relativePath = trimToEmpty(request.getPathInfo());

        // Make sure no one try to screw with us. 
        // This is important as user can literally access any file if we are not careful
        if(isXSSAttack(relativePath) == false) {
            String pathToFile = this.getServletContext().getRealPath(request.getPathInfo());
            File file = new File(pathToFile);

            System.out.println("Looking for file " + file.getAbsolutePath());

            // show a 404 page
            if(!file.exists() || !file.isFile()) {
                httpError(404, response);
            } else {
                try {
                    streamImageFile(file, response);
                } catch(Exception e) {
                    // Tell the user there was some internal server error.\
                    // 500 - Internal server error.
                    httpError(500, response);
                    e.printStackTrace();
                }
            }
        } else {
            // what to do if i think it is a XSS attack ?!?
        }
    }

    private void streamImageFile(File file, HttpServletResponse response) {
        // find the right MIME type and set it as content type
        response.setContentType(getContentType(file));
        BufferedInputStream bis = null;
        BufferedOutputStream bos = null;
        try {
            response.setContentLength((int) file.length());

            // Use Buffered Stream for reading/writing.
            bis = new BufferedInputStream(new FileInputStream(file));
            bos = new BufferedOutputStream(response.getOutputStream());

            byte[] buff = new byte[(int) file.length()];
            int bytesRead;

            // Simple read/write loop.
            while (-1 != (bytesRead = bis.read(buff, 0, buff.length))) {
                bos.write(buff, 0, bytesRead);
            }
        } catch (Exception e) {

            throw new RuntimeException(e);
        } finally {
            if (bis != null) {
                try {
                    bis.close();
                } catch (IOException e) {
                    e.printStackTrace();
                    // To late to do anything about it now, we may have already sent some data to user.
                }
            }
            if (bos != null) {
                try {
                    bos.close();
                } catch (IOException e) {
                    e.printStackTrace();
                    // To late to do anything about it now, we may have already sent some data to user.
                }
            }
        } 
    }

    private String getContentType(File file) {
        if(file.getName().length() > 0) {
            String[] parts = file.getName().split("\\.");
            if(parts.length > 0) {
                // only last part interests me
                String extention = parts[parts.length - 1];
                if(extention.equalsIgnoreCase("jpg")) {
                    return "image/jpg";
                } else if(extention.equalsIgnoreCase("gif")) {
                    return "image/gif"; 
                } else if(extention.equalsIgnoreCase("png")) {
                    return "image/png";
                }
            }
        }
        throw new RuntimeException("Can not find content type for the file " +  file.getAbsolutePath());
    }

    private String trimToEmpty(String pathInfo) {
        if(pathInfo == null) {
            return "";
        } else {
            return pathInfo.trim();
        }
    }

    private void httpError(int statusCode, HttpServletResponse response) {
        try {
            response.setStatus(statusCode);
            response.setContentType("text/html");
            PrintWriter writer = response.getWriter();
            writer.append("<html><body><h1>Error Code: " + statusCode + "</h1><body></html>");
            writer.flush();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    private boolean isXSSAttack(String path) {
        boolean xss = false;
        // Split on the bases of know file separator
        String[] parts = path.split("/|\\\\");

        // Now verify that no part contains anything harmful
        for(String part : parts) {
            // No double dots .. 
            // No colons :
            // No semicolons ;
            if(part.trim().contains("..") || part.trim().contains(":") || part.trim().contains(";")) {
                // Fire in the hole!
                xss = true;
                break;
            }
        }
        return xss;
    }

    /**
     * @see HttpServlet#doPost(Ht/promotions/some.jpgtpServletRequest request, HttpServletResponse response)
     */
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        doGet(request, response);
    }
}

Ok Qui è un servlet che ho scritto in fretta che può trasmettere le immagini:

Ecco l'elenco dei limiti e sapere questioni:

  • Può usufruire vulnerabilità XSS con cura
  • Non produzione pronto uso come riferimento
  • Le immagini devono nella directory dell'applicazione web. Può essere cambiamento facilmente, ma io troppo pigro (che non vale la pena il progetto è troppo piccolo)
  • file
  • Solo streaming JPG, GIF o PNG.

Utilizzo:

diciamo si distribuisce questa applicazione web chiamato le immagini come applicazione separata.

http://www.example.com/images/promotions/promo.jpg

significa che ci dovrebbe essere una directory "promozioni" con l'immagine "promo.jpg" con in questa applicazione web immagini.

PS: Non chiedere il motivo per cui sto facendo questa unica soluzione Servlet Container che succhia grande tempo

.
  <servlet>
    <description></description>
    <display-name>ImageDisplayServlet</display-name>
    <servlet-name>ImageDisplayServlet</servlet-name>
    <servlet-class>com.example.images.ImageDisplayServlet</servlet-class>
  </servlet>
  <servlet-mapping>
    <servlet-name>ImageDisplayServlet</servlet-name>
    <url-pattern>/*</url-pattern>
  </servlet-mapping>

Oh ya configurare il servlet come sopra per ottenere i migliori risultati: P

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