Route to static file in Play! 2.0

后端 未结 9 1746
甜味超标
甜味超标 2021-01-30 14:05

I\'m trying to make a route to a specific static file but everything I\'m trying ends with an error.

I\'ve made 3 different attempts:

1.

GET /fil         


        
相关标签:
9条回答
  • 2021-01-30 14:09

    I have the exact same issue. I followed the advice from @Jamil and managed to get this working for the static file (in my case a favicon) and managed to get the templates to compile but get a new error at runtime when trying to use the view. Relevant code below,

    Change to the route (this route now resolves correctly)

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

    Change to the view (compiles)

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

    New error (only at runtime)

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

    I know this isnt an answer but perhaps it will allow someone to pipe up with one.

    0 讨论(0)
  • 2021-01-30 14:18

    Play java packages public folder in a jar file and this would be a problem if you would like to serve a static file that resolves to an absolute file location in the server. The right way to do is to have your own controller and use it to serve the static file.

    For ex, to serve a file "mystatic.html" that is in the

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

    You would configure this route in your routes file.

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

    and your controller would be implemented as follows.

    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();
            }
        }   
    }
    
    0 讨论(0)
  • 2021-01-30 14:22

    I was experiencing the same issue while I was trying to configure some additional css. It worked with this syntax in the "routes" file

      GET   /css/*file                      controllers.Assets.at(path="/public/css", file)
    
    0 讨论(0)
  • 2021-01-30 14:26

    I ran into the same issue. When I added a second controllers.Assets.at to routes like

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

    the default @routes.Assets.at calls in main.scala.html failed compilation

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

    This would seems to be because of an implicit parameter for which there are multiple matching objects. The solution is to add a leading positional parameter:

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

    Unfortunately, if you go back to having only one assets line in routes, you will have to change to the one-parameter form to avoid a compilation error. Seems like a bug to me.

    0 讨论(0)
  • 2021-01-30 14:30

    Your third attempt was almost right. Instead of

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

    do it like this

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

    I got the same issue before. My route file looks like this.

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

    And I have below reverse route inside views (examples.scala.html)

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

    When I open http://localhost:9000/exmpl, this error showed up.

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

    To fix this issue, I just changed this route

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

    to this

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

    This solution was works for me. I hope it works for you and the others too.

    0 讨论(0)
  • 2021-01-30 14:33

    The solution to this that is cleanest is to create your own AssetsBuilder that will build your static page.

    Create this file in your controllers package - Static.scala

    package controllers
    
    object Static extends AssetsBuilder
    

    Then in your routes you can define your static endpoint

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

    Done. Now the file at /public/html/file.html will be served off of localhost:9000/file

    If you replace the hard code above with a more generic:

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

    then /foo will serve /public/html/foo.html, /bar will serve /public/html/bar.html etc.

    0 讨论(0)
提交回复
热议问题