2017-02-22 3 views
1

Ziel ist es, sowohl öffentliche als auch private Bilder herunterzuladen und zu rendern (z. B. Profilbilder).Dateien mit dem play-Framework nicht finden sendFile-Funktion

Im Play Framework docs (ScalaStream), heißt es:

Wiedergabe einfach zu bedien bietet Helfer für die gemeinsame Aufgabe, eine lokale Datei dienen:

def index = Action { 
    Ok.sendFile(new java.io.File("/tmp/fileToServe.pdf")) 
} 

Wenn Sie diese Datei inline dienen wollen :

def index = Action { 
    Ok.sendFile(
    content = new java.io.File("/tmp/fileToServe.pdf"), 
    inline = true 
) 
} 

Das sieht aus wie w Hut wird benötigt, um das Ziel zu erreichen.

Jetzt habe ich eine Verzeichnisstruktur, wie unten dargestellt, und möchte die Dateien dienen 1.png und 2.png

MyApp 
|_ app 
|_ conf 
|_ public (all public assets) 
    |_ images 
     |_ 1.png 
|_ private (more assets, not public) 
    |_ images 
     |_ 2.png 
|_ ... 

ich eine Controller-Funktion definiert haben, wie folgt:

def sendImage() = Action { 
    // Ok.sendFile(new java.io.File("/public/images/1.png")) 
    // Ok.sendFile(new java.io.File("assets/images/1.png")) 
    Ok.sendFile(new java.io.File("/private/images/1.png")) 
} 

Versuchte verschiedene verschiedene Pfade, absolut, relativ, aber wenn ich diese Controller-Funktion vom Front-End (React/Axios) aus anrufe, gibt es nur "NoSuchFileException" zurück.

aber ich bin in der Lage der öffentlichen Vermögenswerte aus dem Front-End zu machen einfach mit:

<img src='/assets/images/1.png' /> // from the public dir 

Der gleiche Weg nicht aus dem Controller funktioniert. Konnte nicht herausfinden, wie Play seine Pfade erwartet.

Derzeit mit Play 2.5

Irgendwelche Ideen? Danke

+0

Wenn Sie '/' vor dem Dateinamen verwenden, erwartet dies den vollständigen Pfad der Datei und keinen relativen Pfad. Sie müssen von '" /private/images/1.png "' zu '" private/images/1.png "' wechseln, damit es relativ zu Ihrer Anwendung ist. Wenn diese privaten Dateien jedoch vom Benutzer hochgeladen werden, werden sie im Anwendungsverzeichnis als schlechte Methode betrachtet. Was passiert, wenn Sie eine neue Version der Anwendung bereitstellen? Sie werden die Dateien entweder verlieren oder Sie müssen sie während der Bereitstellung kopieren/verschieben. Verfügen Sie also über ein Verzeichnis, das sich außerhalb der Anwendung befindet, um hochgeladene Dateien zu speichern. – marcospereira

Antwort

0

Der Kommentar von @marcospereira hinzufügen müssen, was dazu beigetragen, den Weg zu lösen, danke!

Wenn Sie / vor dem Dateinamen verwenden, erwartet dies den vollständigen Pfad der Datei und keine relative Datei. Sie müssen von /private/images/1.png zu private/images/1.png wechseln, damit es relativ zu Ihrer Anwendung ist.

Aber, wenn diese privaten Dateien vom Benutzer hochgeladen werden, haben sie im Anwendungsverzeichnis als eine schlechte Praxis. Was passiert, wenn Sie eine neue Version der Anwendung bereitstellen? Sie werden die Dateien entweder verlieren oder Sie müssen sie während der Bereitstellung kopieren/verschieben. Verfügen Sie also über ein Verzeichnis, das sich außerhalb der Anwendung befindet, um hochgeladene Dateien zu speichern.

0

injizieren play.api.Application Objekt in Ihrem Controller und verwenden Sie die getFile Methode im Anwendungsobjekt definiert, wie unten gezeigt.

class JobInstanceController @Inject()(protected val app: Application) extends Controller { 
    def test = Action { 
    Ok.sendFile(app.getFile("public/images/1.png")) 
    } 
}