playframework - Ruta al archivo estático en Play! 2.0
routes playframework-2.0 (9)
Estoy tratando de hacer una ruta a un archivo estático específico, pero todo lo que intento termina con un error.
He hecho 3 intentos diferentes:
1.
GET /file staticFile:/public/html/file.html
El error que recibo:
Compilation error
string matching regex `/z'' expected but `:'' found
2.
GET /file controllers.Assets.at(path="/public/html", "file.html")
El error que recibo:
Compilation error
Identifier expected
3.
GET /file controllers.Assets.at(path="/public/html", file="file.html")
El error que recibo: (y este es el más extraño)
Compilation error
not enough arguments for method at: (path: String, file: String)play.api.mvc.Call. Unspecified value parameter file.
La parte extraña del tercer error es que se arroja en un archivo diferente (app / views / main.scala.html) en la siguiente línea:
<link rel="stylesheet" media="screen" href="@routes.Assets.at("stylesheets/main.css")">
Todos estos métodos se encontraron en la documentación oficial y / o subprocesos aquí en stackoverflow. ¿Que me estoy perdiendo aqui?
Gracias.
Esta habilidad todavía no se ha agregado, como sé. Pero si alguien necesita respuesta, como una opción, se puede crear un controlador auxiliar para estos fines:
object StaticFile extends Controller {
def html(file: String) = Action {
var f = new File(file)
if (f.exists())
Ok(scala.io.Source.fromFile(f.getCanonicalPath()).mkString).as("text/html");
else
NotFound
}
}
y luego en la configuración de rutas
GET / controllers.StaticFile.html(file = "public/index.html")
Estaba experimentando el mismo problema mientras intentaba configurar algunos CSS adicionales. Funcionó con esta sintaxis en el archivo "rutas"
GET /css/*file controllers.Assets.at(path="/public/css", file)
IIRC, cambio
<link rel="stylesheet" media="screen" href="@routes.Assets.at("stylesheets/main.css")">
A
<link rel="stylesheet" media="screen" href="@routes.Assets.at("stylesheets/", "main.css")">
Estoy hablando de tu tercer intento
Además, ten cuidado con extra /
EDITAR
GET /assets/main.css controllers.Assets.at(path="/public", file="/stylesheets/main.css")
Suponiendo que su recurso está en /public/stylesheets/main.css
Juegue a la carpeta pública de paquetes java en un archivo jar y esto sería un problema si desea servir un archivo estático que se resuelve en una ubicación de archivo absoluta en el servidor. La forma correcta de hacerlo es tener su propio controlador y usarlo para servir el archivo estático.
Por ejemplo, para servir un archivo "mystatic.html" que está en el
<your playhome>
|-----<myfolder>
|------mystatic.html
Debería configurar esta ruta en su archivo de rutas.
GET /mystatic mypackage.mycontrollers.Static.getFile(path="/myfolder/mystatic.html")
y su controlador se implementará de la siguiente manera.
package mypackage.mycontroller;
import java.io.File;
import com.google.inject.Inject;
import com.google.inject.Provider;
import play.Application;
import play.mvc.Controller;
import play.mvc.Result;
import play.mvc.Results;
public class Static extends Controller {
@Inject
Provider<Application> app;
public Result getFile(String path){
File file = app.get().getFile(path);
if(file.exists()){
return ok(file);
}else{
return Results.notFound();
}
}
}
La solución a esto que es más limpia es crear su propio AssetsBuilder que construirá su página estática.
Cree este archivo en su paquete de controladores - Static.scala
package controllers
object Static extends AssetsBuilder
Luego, en sus rutas puede definir su punto final estático
GET /file controllers.Static.at(path="/public/html", "file.html")
Hecho. Ahora el archivo en /public/html/file.html
se servirá fuera de localhost:9000/file
Si reemplaza el código difícil anterior con un más genérico:
GET /*file controllers.Static.at(path="/public/html", *file + ".html")
then /foo
servirá /public/html/foo.html
, /bar
servirá /bar
/public/html/foo.html
/bar
/public/html/foo.html
/bar
/public/html/bar.html
etc.
Me encontré con el mismo problema. Cuando agregué un segundo controllers.Assets.at
Asset.at a rutas como
GET /assets/*file controllers.Assets.at(path="/public", file)
GET /assets2/*file controllers.Assets.at(path="/public2", file)
las llamadas @routes.Assets.at
routes.Assets.at predeterminadas en main.scala.html compilación fallida
Compilation error
not enough arguments for method at: (path: String, file: String)play.api.mvc.Call. Unspecified value parameter file.
Esto parece ser debido a un parámetro implícito para el que hay múltiples objetos coincidentes. La solución es agregar un parámetro posicional principal:
href="@routes.Assets.at("/public","/css/main.css")"
Desafortunadamente, si vuelve a tener solo una línea de activos en las rutas, tendrá que cambiar al formulario de un parámetro para evitar un error de compilación. Me parece como un insecto.
No estoy totalmente seguro de si esto es correcto, pero esto es lo que estamos usando para mapear una carpeta pública que contiene nuestras imágenes, javascripts ... etc.
# Map static resources from the /public folder to the /assets URL path
GET /assets/*file controllers.Assets.at(path="/public", file)
Tengo exactamente el mismo problema. Seguí el consejo de @Jamil y logré que esto funcionara para el archivo estático (en mi caso, un favicon) y logré que las plantillas se compilaran, pero aparece un nuevo error en el tiempo de ejecución cuando intento usar la vista. Código relevante a continuación,
Cambiar a la ruta (esta ruta ahora se resuelve correctamente)
GET /favicon.ico controllers.Assets.at(path="/public/images", file="favicon.png")
Cambiar a la vista (compila)
<link rel="stylesheet" media="screen" href="@routes.Assets.at("stylesheets/","main.css")">
Nuevo error (solo en tiempo de ejecución)
[MatchError: (stylesheets/,main.css) (of class scala.Tuple2)]
// @LINE:29
// @LINE:28
def at(path:String, file:String) = {
(path, file) match {
// @LINE:28
case (path, file) if path == "/public" => Call("GET", "/assets/" + implicitly[PathBindable[String]].unbind("file", file))
Sé que esta no es una respuesta, pero tal vez le permita a alguien buscar una.
Tu tercer intento fue casi correcto. En lugar de
GET /file controllers.Assets.at(path="/public/html", file="file.html")
Hazlo asi
GET /file controllers.Assets.at(path="/public", file="html/file.html")
Tengo el mismo problema antes. Mi archivo de ruta se ve así.
# Application
GET / controllers.Assets.at(path="/public/html", file="static.html")
GET /exmpl controllers.Examples.index
# Resources
GET /assets/*file controllers.Assets.at(path="/public", file)
Y tengo debajo de la ruta inversa dentro de las vistas ( examples.scala.html
)
@routes.Assets.at("imagefolder") #try to generate path to /public/imagefolder.
Cuando abro http://localhost:9000/exmpl
, http://localhost:9000/exmpl
este error.
not enough arguments for method at: (path: String, file: String)play.api.mvc.Call. Unspecified value parameter file.
Para solucionar este problema, acabo de cambiar esta ruta
GET / controllers.Assets.at(path="/public/html", file="static.html")
a esto
GET / controllers.Assets.at(path="/public", file="html/static.html")
Esta solución fue para mí. Espero que funcione para ti y para los demás también.