image scala playframework playframework-2.2 playframework-2.3

image - Play Framework: manejo de archivos dinámicos creados(imágenes) en modo PRODUCCIÓN



scala playframework (2)

Play lee los archivos de la ruta de clase (que incluye el directorio de activos). En la JVM, el classpath es inmutable; una vez que se inicia, los archivos agregados a las carpetas en el classpath no se agregarán realmente al classpath.

Esto funciona en modo de desarrollo porque Play vuelve a cargar el classpath cada vez que detecta un cambio. Esa misma recarga en caliente no está habilitada en la producción (por una buena razón).

Estoy tratando de permitir a los usuarios subir fotos al servidor y luego verlas (todos los usuarios pueden ver todas las fotos) en producción (NO desarrollo). Mientras estoy en modo de desarrollo, todo es simple: puedo subir los archivos a la carpeta pública y luego leer desde allí, en modo de producción ya no tengo acceso a la carpeta pública (ya que este enfoque es para accesos estáticos y no dinámicos) .

Entonces, tengo 2 problemas:

  1. Cargar: actualmente no puedo entender cómo guardar las fotos cargadas en una carpeta específica, sin usar una ruta absoluta a la ubicación donde quiero guardar las fotos.

Aquí está el código para cargar (de manera similar a esta guía - https://www.playframework.com/documentation/2.4.x/ScalaFileUpload ):

def uploadPhoto = Action(parse.multipartFormData) { request => import play.api.mvc.MultipartFormData import play.api.libs.Files.TemporaryFile import java.io.File import java.nio.file.Path import java.nio.file.Paths try { val multipartForm: MultipartFormData[TemporaryFile] = request.body val pathDev: Path = Paths.get("./public/img"); val pathProduction: Path = Paths.get("/...<[full path]>.../public/img"); val imgPath = if (Files.exists(pathDev)) { pathDev.toString() } else { pathProduction.toString() } val newFile = img.get.ref.moveTo(new File(s"$imgPath/$imgName")) // [HERE I save the path to my DB] Ok(Json.obj("imgName" -> imgName)) } catch { case e: Exception => BadRequest("unknown error") } }

  1. No me queda claro cómo enviar las imágenes cargadas a los usuarios que desean verlas. Quiero cambiar dinámicamente el scr en la etiqueta img html para mostrar la imagen relevante, así: $ ("# img"). Attr ("src", ''assets / img / 1.jpg'');

Pero como la carpeta pública no está disponible, las imágenes "no están allí" (al menos hasta que "escenifique" el proyecto y lo vuelva a ejecutar - https://www.playframework.com/documentation/2.4.x/Assets )

Probé el siguiente enfoque ( https://www.playframework.com/documentation/2.4.x/ScalaStream ): He agregado la siguiente línea a mi archivo conf / routes: GET / img /: controllers de nombre de archivo.MyController.getPhoto ( nombre del archivo)

y definió la siguiente función en el controlador: def getPhoto (filename: String) = Acción {Ok.sendFile (new java.io.File ("./ img /" + filename))}

Pero el navegador está descargando el archivo en lugar de mostrarlo ...

Estos están relacionados: Manejo de archivos dinámicos creados en el juego 2 ¿Cómo servir archivos cargados en Play! 2 usando Scala?

Cualquier ayuda será muy apropiada.


Así es como soluciono esto

NÚMERO 1

Para cargar la ruta del archivo, en juego puede definir configuraciones en el archivo conf / application.conf, y puede usar diferentes archivos para el modo de producción, usando -Dconfig.file = / path / to / the / file.

Así que definí un atributo llamado myapp.image.base, en el modo de depuración simplemente lo configuré en "", y en el modo de producción (creé un archivo llamado conf / application.prod.conf), le puse una ruta de acceso absoluta. Por lo tanto, en mi código, siempre uso el siguiente comando para la ruta del archivo (está en Java, pero debería encontrar una forma similar en Scala para leer la configuración)

Play.application().configuration().getString("myapp.image.base")+"img"

NÚMERO 2

Para servir imágenes Necesita crear un enrutador. Primero en su archivo de rutas, agregue algo como esto:

GET /user/images/:name controllers.Application.imageAt(name:String)

Y escriba un lector de archivos simple en acción imageAt which return the file in stream. De nuevo, mi muestra está en Java, pero debe archivarla con Scala

File imageFile = new File(ReportFileHelper.getImagePath()); if (imageFile.exists()) { //resource type such as image+png, image+jpg String resourceType = "image+"+imageName.substring(imageName.length()-3); return ok(new FileInputStream(imageFile)).as(resourceType); } else { return notFound(imageFile.getAbsoluteFile()); }

Después de eso, las imágenes son accesibles desde url / user / images /