web-dev-qa-db-fra.com

Route vers un fichier statique dans Play! 2.0

J'essaie de créer un itinéraire vers un fichier statique spécifique, mais tout ce que j'essaie se termine par une erreur.

J'ai fait 3 tentatives différentes:

1.

GET /file   staticFile:/public/html/file.html

L'erreur que j'obtiens:

Compilation error
string matching regex `\z' expected but `:' found

2.

GET /file   controllers.Assets.at(path="/public/html", "file.html")

L'erreur que j'obtiens:

Compilation error
Identifier expected

3.

GET /file   controllers.Assets.at(path="/public/html", file="file.html")

L'erreur que j'obtiens: (et c'est la plus étrange)

Compilation error
not enough arguments for method at: (path: String, file: String)play.api.mvc.Call. Unspecified value parameter file.

La partie étrange de la 3e erreur est qu'elle est jetée dans un fichier différent (app/views/main.scala.html) sur la ligne suivante:

<link rel="stylesheet" media="screen" href="@routes.Assets.at("stylesheets/main.css")">

Toutes ces méthodes ont été trouvées dans la documentation officielle et/ou les discussions ici sur stackoverflow. Qu'est-ce que j'oublie ici?

Merci.

32
Nitzan Tomer

IIRC, changement

<link rel="stylesheet" media="screen" href="@routes.Assets.at("stylesheets/main.css")">

À

<link rel="stylesheet" media="screen" href="@routes.Assets.at("stylesheets/", "main.css")">

Je parle de ta troisième tentative

Attention aussi aux extra /

MODIFIER

GET /assets/main.css    controllers.Assets.at(path="/public", file="/stylesheets/main.css")

En supposant que votre ressource se trouve dans /public/stylesheets/main.css

18
Jamil

Je ne suis pas totalement sûr que ce soit correct, mais c'est ce que nous utilisons pour mapper un dossier public contenant nos images, javascripts ... etc.

# Map static resources from the /public folder to the /assets URL path
GET     /assets/*file               controllers.Assets.at(path="/public", file)
13
Nick

Comme je le sais, cette capacité n'a toujours pas été ajoutée. Mais si quelqu'un a besoin d'une réponse, en option, un contrôleur d'assistance peut être créé à ces fins:

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
  }

}

puis dans la configuration des routes

GET     /               controllers.StaticFile.html(file = "public/index.html")
13
Andrey Antonov

La solution la plus propre à cela est de créer votre propre AssetsBuilder qui construira votre page statique.

Créez ce fichier dans votre package de contrôleurs - Static.scala

package controllers

object Static extends AssetsBuilder

Ensuite, dans vos itinéraires, vous pouvez définir votre point de terminaison statique

GET /file   controllers.Static.at(path="/public/html", "file.html")

Terminé. Maintenant, le fichier à /public/html/file.html sera servi à partir de localhost:9000/file

Si vous remplacez le code dur ci-dessus par un code plus générique:

GET /*file   controllers.Static.at(path="/public/html", *file + ".html")

puis /foo servira /public/html/foo.html, /bar servira /public/html/bar.html etc.

10
Michael Allen

Votre troisième tentative avait presque raison. Au lieu de

GET /file   controllers.Assets.at(path="/public/html", file="file.html")

fais-le comme ça

GET /file   controllers.Assets.at(path="/public", file="html/file.html")

J'ai eu le même problème avant. Mon fichier d'itinéraire ressemble à ceci.

# 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)

Et j'ai ci-dessous l'itinéraire inverse à l'intérieur des vues (examples.scala.html)

@routes.Assets.at("imagefolder")   #try to generate path to /public/imagefolder.

Quand j'ouvre http://localhost:9000/exmpl, cette erreur est apparue.

not enough arguments for method at: (path: String, file: String)play.api.mvc.Call. Unspecified value parameter file.

Pour résoudre ce problème, je viens de changer cet itinéraire

GET /     controllers.Assets.at(path="/public/html", file="static.html")

pour ça

GET /     controllers.Assets.at(path="/public", file="html/static.html")

Cette solution a fonctionné pour moi. J'espère que ça marche pour vous et les autres aussi.

5
user2737506

J'ai exactement le même problème. J'ai suivi les conseils de @Jamil et j'ai réussi à faire fonctionner le fichier statique (dans mon cas, un favicon) et j'ai réussi à compiler les modèles mais à obtenir une nouvelle erreur lors de l'exécution lorsque j'essaie d'utiliser la vue. Code pertinent ci-dessous,

Modification de l'itinéraire (cet itinéraire se résout désormais correctement)

GET     /favicon.ico                controllers.Assets.at(path="/public/images", file="favicon.png")

Passer à la vue (compile)

<link rel="stylesheet" media="screen" href="@routes.Assets.at("stylesheets/","main.css")">

Nouvelle erreur (uniquement lors de l'exécution)

[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))

Je sais que ce n'est pas une réponse, mais peut-être que cela permettra à quelqu'un d'en avoir une.

4
Ben Boyter

Je rencontrais le même problème pendant que j'essayais de configurer des CSS supplémentaires. Il fonctionnait avec cette syntaxe dans le fichier "routes"

  GET   /css/*file                      controllers.Assets.at(path="/public/css", file)
3
loic23

J'ai rencontré le même problème. Quand j'ai ajouté un deuxième controllers.Assets.at vers des itinéraires comme

GET  /assets/*file   controllers.Assets.at(path="/public", file)
GET  /assets2/*file  controllers.Assets.at(path="/public2", file)

le défaut @routes.Assets.at les appels dans main.scala.html ont échoué lors de la compilation

Compilation error
not enough arguments for method at: (path: String, file: String)play.api.mvc.Call. Unspecified value parameter file.

Cela semble être dû à un paramètre implicite pour lequel il existe plusieurs objets correspondants. La solution consiste à ajouter un paramètre positionnel de premier plan:

href="@routes.Assets.at("/public","/css/main.css")"

Malheureusement, si vous revenez à n'avoir qu'une seule ligne d'actifs dans les itinéraires, vous devrez passer au formulaire à un paramètre pour éviter une erreur de compilation. Ça ressemble à un bug pour moi.

1
Eric Drechsel

Jouer Java contient le dossier public des packages dans un fichier jar et cela poserait un problème si vous souhaitez servir un fichier statique qui se résout en un emplacement de fichier absolu sur le serveur. La bonne façon de procéder est pour avoir votre propre contrôleur et l'utiliser pour servir le fichier statique.

Par exemple, pour servir un fichier "mystatic.html" qui est dans le

<your playhome>
    |-----<myfolder>
        |------mystatic.html

Vous devez configurer cette route dans votre fichier de routes.

GET /mystatic           mypackage.mycontrollers.Static.getFile(path="/myfolder/mystatic.html")

et votre contrôleur serait implémenté comme suit.

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();
        }
    }   
}
1
Droidman