Frage

Ich schreibe eine einfache Anwendung, die ein Nutzer Bilder hochladen kann. Nach dem Upload markiert, der Benutzer sie kann oder sie entfernen.

ich herausgefunden, wie die Dateien zu laden und speichern, sobald die Dateien hochgeladen werden. Ich halte Verfolgung eines globalen Pfad, in dem Bilder gehalten werden. In der Datenbank halte ich die Meta-Daten über die Bilder wie Dateiname, Tags, etc.

Ich bin mit Java / JSP (speziell Stripes Rahmen aber mein Problem ist generisch).

Meine Frage ist, wo ich diese Bilddateien halten, sobald sie hochgeladen werden?

Im Moment habe ich zwei Web-Anwendungen auf einem Tomcat-Server bereitgestellt. Eine Haupt-Web-Anwendung und andere ist die, wo ich die Bilder hochgeladen werden.

Aber das funktioniert nicht, da ich nicht die hochgeladenen Bilder in der Hauptanwendung sehen kann, bis ich umschichten / Tomcat neu starten.

Es scheint, wie Tomcat nicht neu ist Pick hochgeladenen Bilder automatisch.

Hat jemand irgendwelche Lösungen?

Dies ist ein einfaches Projekt, so will ich nicht in einer Datenbank speichern oder Apache für Bilder verwenden. Das ist alles einfach zu kompliziert für dieses kleine Projekt.

Danke.

War es hilfreich?

Lösung

Auf jeden Fall nicht speichert die Bilder in der Datenbank, aber Sie werden den Bildpfad in der Datenbank gespeichert werden sollen. Dies ermöglicht es Ihnen, das Bild zu speichern, einfach überall.

Da Sie zwei tomcat-Anwendungen verwenden, die beste Wahl können die Bilder außerhalb von jeder App zu speichern und das Bild an den Benutzer streamen zurück statt tomcat lassen verwalten Sie die Dateien. Ansonsten würde ich fragen, warum Sie dies zu tun mit zwei Web-Anwendungen versuchen.

Andere Tipps

Allerdings hochgeladene Bilder in dem Web-App-Verzeichnis zu speichern ist nicht eine kluge Sache zu tun, und Sie wissen es.

By the way, können Sie dieses Stackoverflow fädeln , diskutiert in letzter Zeit, wo die Bilder zu speichern. Es ist vielleicht nicht Ihr Problem lösen, werden Sie sicherlich mehr Vertrauen auf das, was Sie tun.

Ich habe dies auf verschiedene Weise gelöst werden.

Zuerst wird die nicht tragbare Art und Weise, ist, dass Glassfish (und ich glaube, Tomcat als auch) können Sie ein externes Verzeichnis in das webapps Hierarchie abzubilden. Das funktioniert wirklich gut und genau das tut, was Sie wollen. Damit können Sie speichern Sie Ihre Bilder in einem externen Verzeichnis von Ihrem Webapp entfernt, aber immer noch dienen sie.

Allerdings ist diese Technik nicht tragbar.

Die Art und Weise ich es portably getan haben, ist durch einen Filter zu schaffen.

Sie legen den Filter irgendwo offensichtlich, sagen Sie "/ images".

Was ist der Filter tut, ist dies:

  • überprüft es für das Bild (oder irgendetwas, es funktioniert mit jeder statischen Ressource) in einem speziellen Verzeichnis innerhalb des Webapp. Für unser Beispiel werden wir die URL "/ webapp / images".

  • verwenden
  • , wenn die Datei nicht vorhanden ist, kopieren wir die Datei von Ihrem externen Standort in an die entsprechende Stelle innerhalb der Webapp. So lassen Sie uns sagen, dass die reqyest url ist "/images/banner.gif". Und dass Ihre Dateien auf der Festplatte in „/ home / app / images“ gespeichert sind. Also, unsere Quelldatei „/home/app/images/banner.gif“. Wir kopieren sie dann, wo wir es in der Webapp Baum wollen. Wir verwenden „ServletContext.getRealPath“ für diese. So wird das Ziel sein "ServletContext.get RealPath (" / webapp / images / banner.gif "). Kopieren Sie einfach die Quelle zum Ziel.

  • Wenn die Datei bereits existiert, oder jetzt existiert, einfach sich auf das eigentliche Bild auf /webapp/images/banner.gif.

effektiv beenden Sie einen Dateicache in Ihrem Webapps Deployment Baum mit bis. Die Kehrseite ist, dass es ein Cache ist, so muss es gepflegt werden (das heißt, sollten Sie überprüfen, ob das Original neuer als Cache ist, stellen Sie sicher, dass Sie löschen, wenn die Quelle gelöscht, etc.). Außerdem ist es dupliziert Ihre Ressourcen, so dass die Bilder verbrauchen schließlich doppelt so viel Speicherplatz. Schließlich gibt es die anfänglich Kosten für eine Kopie beim Start.

Allerdings ist es Arbeit, und es verhindert, dass Sie mit Ihrem eigenen Code dienen statische Ressourcen. (Was die dritte Lösung ist, Karte einen Filter / Servlet die URLs abfangen und es ist einfach, um sich selbst zu streamen.)

Ich würde in Tomcat auf das Konstrukt aussehen (vorausgesetzt, es existiert) für Sie die Zuordnung zu tun. Ich weiß, dass es in Glassfish existiert. (Google alternatedocroot für Glassfish zu sehen, wie es funktioniert.)

Ich war mit zwei Web-Anwendungen zu vermeiden, über die hochgeladenen Bilder zu schreiben, falls ich eine neue Haupt IST-Datei erneut bereit.

Aber wie Sie erwähnen gibt es keine andere Wahl, als sie durch ein Servlet zu streamen oder etwas, was ich denke, ich kann sie außerhalb tomcat Verzeichnis halten.

Ich wollte dieses Streaming-Servlet zu vermeiden, zu schreiben. Einfach zu kleines Projekt mit dem ganzen Schlamassel zu tun (wie richtigen Inhaltstyp, 404, etc.), während des Streaming-Servlet zu schreiben.

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 ist hier ein Servlet, das ich schrieb schnell, dass können Bilder streamen:

Hier ist die Liste der Einschränkungen und weiß Themen:

  • Kann Gebrauch mit Vorsicht Verwundbarkeit XSS haben
  • Nicht Produktion bereit Verwendung als Referenz
  • Bilder müssen in der Web-Anwendung-Verzeichnis. ändern sich leicht, aber ich zu faul (es ist nicht wert das Projekt zu klein ist)
  • Nur streamen jpg, gif oder png-Dateien.

Verwendung:

Lassen Sie uns sagen, dass Sie diese Web-Anwendung bereitstellen genannt Bilder als separate Anwendung.

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

Es sollte also ein Verzeichnis in „Aktionen“ mit Bild „promo.jpg“ sein mit diesem Bildern Web-Anwendung.

PS: Frag nicht, warum ich diese Servlet Container einzige Lösung mache die große Zeit saugt

.
  <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 konfigurieren Sie Ihre Servlets wie oben für beste Ergebnisse: P

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top