Asset mapping outside public folder on Play framew

2019-02-23 17:00发布

We have huge list of images that we need to store in an external path.. i.e outside of play application folder.

How can we make it available to play as an asset so it streams it as a web server?

4条回答
我欲成王,谁敢阻挡
2楼-- · 2019-02-23 17:48

Play 2.5

file: routes

GET  /external_resources/*file controllers.ImagesController.getImage(path="/home/project_name/external/images", file: String)

file: ImagesController

package controllers;

import play.mvc.Controller;
import play.mvc.Result;

import java.io.File;

/**
 * Created by js on 6/1/17.
 */
public class ImagesController extends Controller {

public Result getImage(String path, String image) {
    System.out.println(path);
    System.out.println(image);
    image = image.replace("%20", " ");
    File file = new File(path + image);

    return ok(file);
  }
}
查看更多
你好瞎i
3楼-- · 2019-02-23 17:55

In the interests of completeness, I've experienced this problem many times and there has been no sufficient answer for it.

Typically nginx would face the outside world and reverse-proxy back into the application server. You do not want to serve files straight from Play especially if you're building paths yourself which may present security risks. Let the experts handle static files, ie nginx.

Play Framework supports sbt-native-packager's "dist" directory which will attach any files in there right inside the distribution ZIP package [1]. Here is the documentation for that:

dist    → Arbitrary files to be included in your projects distribution

For use cases such as controlled downloads use nginx's X-Accel where via a response header you tell nginx what file to send back to the client.


TLDR: use nginx for what it's made for, use Play for what it's made for.

查看更多
萌系小妹纸
4楼-- · 2019-02-23 18:03

You've probably seen Play's documentation about Assets. Additionally to Play's standard assets you can define your own.

In conf/routes you need to add a line for your external asset:

# Static resources (not managed by the Play framework)
GET     /my_external_assets/*file         controllers.ExtAssets.at(file)
# Play's standard assets
GET     /assets/*file                     controllers.Assets.at(path = "/public", file)

And then you have to define your assets controller. A simple example how it could be done:

public class ExtAssets extends Controller {

    public Result at(String filePath) {
        File file = new File(filePath);
        return ok(file, true);
    }
}
查看更多
你好瞎i
5楼-- · 2019-02-23 18:04

A hacky solution would be to include in your sbt play public folder a symlink to the location you want to load the files. The symlink will be packaged in the assembly and will be functional at run time.

cd ~/your/playframework/awesome/project/public
ln -s '/var/lib/funky-data-set-for-my-awesome-project/' funky-data

Now you can use in your routes file something like:

GET         /funky/assets/*file                controllers.Assets.at(path="/public/funky-data", file)

The downside of this is that your stage/dev/prod environment must have that content you need at the same location.

查看更多
登录 后发表回答