Play框架上公共文件夹外的资产映射

5
我们有大量的图片需要存储在play应用程序文件夹之外的外部路径中。如何将其作为资产使其能够在web服务器上流式传输?

1
你不需要用">"尖括号开头来提问。这会导致整个问题被格式化为摘录/块状。 - Martin
1
抱歉这是我的第一个问题,以后会加以纠正。感谢更新。 - Nishanth Chakrapani
4个回答

7
你可能已经看过 Play 的 有关资产的文档。除了 Play 的标准资产外,你还可以定义自己的资产。
conf/routes 中,你需要添加一行代码来引入你的外部资产:
# 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)

然后您需要定义资产控制器。以下是一个简单的示例:

public class ExtAssets extends Controller {

    public Result at(String filePath) {
        File file = new File(filePath);
        return ok(file, true);
    }
}

3
这个安全吗?当filePath被设置为"../conf/application.conf"时,请回答。 - ScalaWilliam
1
它会返回'../conf/application.conf'的内容,这可能不是你想要的。我只是举了一个简单的例子。如果你想要额外的限制,你必须自己添加。 :) - Kris

2
为了完整起见,我已经多次遇到这个问题,但没有足够的答案解决它。
通常nginx会面向外部世界,反向代理回应用服务器。您不希望直接从Play中提供文件,特别是如果您自己构建路径可能会存在安全风险。让专家处理静态文件,即nginx。 Play Framework支持sbt-native-packager的"dist"目录,其中将附加任何文件在分发ZIP软件包[1] 中。这是相关文档:
dist    → Arbitrary files to be included in your projects distribution

对于像受控下载这样的用例,请使用nginx的X-Accel,通过响应头告诉nginx要向客户端发送哪个文件。
TLDR: 使用nginx处理它所擅长的事情,使用Play处理它所擅长的事情。

nginx并不适合用于授权文件服务。除非你只是将所有文件公开? - latj
如果需要,您可以在nginx中委派授权。请参见:http://nginx.org/en/docs/http/ngx_http_auth_request_module.html - ScalaWilliam

0

Play 2.5

文件:路由

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

文件: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);
  }
}

0
一个hacky的解决方案是在你的sbt play公共文件夹中包含一个符号链接,指向你想要加载文件的位置。这个符号链接将被打包到程序集中,并在运行时起作用。
cd ~/your/playframework/awesome/project/public
ln -s '/var/lib/funky-data-set-for-my-awesome-project/' funky-data

现在你可以在你的路由文件中使用类似这样的代码:

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

这样做的缺点是,您的阶段/开发/生产环境必须在相同的位置具有您所需的内容。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接