Route to static file in Play! 2.0

2020-05-13 16:09发布

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 /file   staticFile:/public/html/file.html

The error I get:

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

2.

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

The error I get:

Compilation error
Identifier expected

3.

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

The error I get: (and this is the weirdest)

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

The weird part about the 3rd error is that it's thrown in a different file (app/views/main.scala.html) on the following line:

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

All of these methods were found in the official documentation and/or threads here on stackoverflow. What am I missing here?

Thanks.

9条回答
Emotional °昔
2楼-- · 2020-05-13 16:32

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();
        }
    }   
}
查看更多
Rolldiameter
3楼-- · 2020-05-13 16:37

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.

查看更多
Root(大扎)
4楼-- · 2020-05-13 16:39

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.

查看更多
登录 后发表回答