Play生产模式下java.io.FileNotFoundException那点事

之前”用Scala+Play构建地理数据查询接口”那篇文章里,用到的数据是json格式的文本文件area.json,存放在conf/jsons文件夹下。最开始是放在public/文件夹下,在线上准生产模式下运行:

activator dist

得到mosquito-1.0.zip压缩包,解压后:

去/bin目录下运行mosquito脚本报错:

java.io.FileNotFoundException

然后就去解压的mosquito-1.0/看发现并没有public文件夹,由此可见public文件夹在dist打包时被编译合并到其他文件夹下了(至于编译后具体在哪,需要看源码)。但是同时还发现conf/文件夹还存在,于是解决办法也简单,就将area.json放到conf/jsons,仔重新:

打包(activator dist) –> 解压 –> 运行(mosquito)

一切正常。

本以为这个事情到此就已经彻底解决了,然并卵。

之后写了“用Play实现文件上传与下载功能(超简单!)”,是直接在本地windows环境开发模式运行的,没有发现问题。之后将那个做了修改:上传图片后直接将图片显示到网页上。这个需求在发表文章时,在文章中插入图片并预览要用到。那么这个时候,就需要上传之后返回文件地址,通过routes中:

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

来访问,此时上传的文件夹在public/upload下,此时在开发模式下也完全没有问题。

但是想到上传文件放到public/下并不合理,如果public/下的css,image等静态文件比较多或者上传的文件多了的话也比较混乱,再者,放到public/下生产模式下根本无法运行成功。于是在项目根目录新建res文件夹,修改上传文件位置,此时文件可以上传到此,但是有出现新的问题:返回的文件地址通过“GET     /assets/*file”无法获取,http code 404.

通过查阅官方文档得知:

However, if you define two mappings for the Assets.at action, like this:

GET  /javascripts/*file        controllers.Assets.at(path="/public/javascripts", file)
GET  /images/*file             controllers.Assets.at(path="/public/images", file)

You will then need to specify both parameters when using the reverse router:

<script src="@routes.Assets.at("/public/javascripts", "jquery.js")"></script>
<image src="@routes.Assets.at("/public/images", "logo.png")">

于是改为:

GET  /javascripts/*file        controllers.Assets.at(path="/public", file)
GET  /res/file             controllers.Assets.at(path="/res",file)

此时要将:

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

改为:

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

这段代码中”@routes.Assets.at….”是反向路由,routes中配置了2个这个,所以需要给相对准确的路径,否则导致反向路由无法匹配成功。

这个时候运行,还是无法通过 GET /res  访问res/下的文件,不知为何。

在stackoverflow.com找到如下解决方法:

在controllers包下创建resourceCtrl并加入:

object resourceCtrl extends Controller{

    val AbsolutePath = """^(/|[a-zA-Z]:\\).*""".r

    def at(rootPath: String, file: String): Action[AnyContent] = Action { request =>

        val fileUrlDeCode = java.net.URLDecoder.decode(file,"utf-8");   //中文需要URLDecoder

        val fileToServe = rootPath match {
            case AbsolutePath(_) => new File(rootPath, fileUrlDeCode)
            case _ => new File(Play.application.getFile(rootPath), fileUrlDeCode)
        }

        if (fileToServe.exists) {
            Ok.sendFile(fileToServe, inline = true)
        } else {
            Logger.error("Photos controller failed to serve photo: " + fileUrlDeCode)
            NotFound
        }
    }
}

将之前的routes中GET /res  改为:

GET         /resource/*file          controllers.resourceCtrl.at(path="/",file)

运行一下,都ok,问题都解决(开发模式下)。

然后再生产模式下运行,通过routes中GET /res获取上传的文件,出错:

java.io.FileNotFoundException: D:\mosquito-project\mosquito\target\universal\mosquito-1.0\mosquito-1.0\bin\res (系统找不到指定的路径。)

搞了半天,又回到原点。

但是注意那个报错信息,是:mosquito-1.0\bin  ,这个地址是 Play.application.getFile获取的。这说明了什么?

这说明通过 Play.application(Play.current.path)获取到的path直接到项目根目录下的bin/文件夹下,而不是项目的根目录。

正确的地址应该是:

D:\mosquito-project\mosquito\target\universal\mosquito-1.0\mosquito-1.0\res

当是我把Play.application获取到的地址toString替换正确的时候,出现 “拒绝访问”。

但是我吧相同的程序放到linux上运行时,一切正常,一切正常,一切正常!  通过打印 Play.current.path 时,路径也正确是根目录。

而且,同时我也注意到:

windows上生产模式运行生成的logs文件夹在bin/下

linux上生产模式运行生成的logs文件夹在根目录下

这个我目前还不知道是为何,再研究研究。

时间: 2024-10-25 06:46:38

Play生产模式下java.io.FileNotFoundException那点事的相关文章

keytool 错误: java.io.FileNotFoundException: 拒绝访问

keytool 错误: java.io.FileNotFoundException: 拒绝访问 打开命令行,切换到D:\AndroidStudioProjects\MyApplication\app目录 keytool 在JDK的/bin目录下,比如:/opt/jdk/bin 用以下的命令生成一个证书: keytool -genkey -alias android.key -keyalg RSA -validity 20000 -keystore android.key 老是报如题的错误: 后来

om.exception.DaoException: java.io.FileNotFoundException: D:\Users\liuyangOS2237\Workspaces\MyEclipse%2010\Zhuce\WebRoot\WEB-INF\classes\users.xml (系统找不到指定的路径。解决

com.exception.DaoException: java.io.FileNotFoundException: D:\Users\liuyangOS2237\Workspaces\MyEclipse%2010\Zhuce\WebRoot\WEB-INF\classes\users.xml (系统找不到指定的路径.) at com.dao.impl.UserDaoDom4jImpl.addUser(UserDaoDom4jImpl.java:84) at com.test.UserDaoDo

【c3p0】报错:java.io.FileNotFoundException: Resource not found at path &#39;/mchange-log.properties&#39;

配置项目启动初始,报错如下: 1 java.io.FileNotFoundException: Resource not found at path '/mchange-commons.properties'. 2 at com.mchange.v2.cfg.BasicPropertiesConfigSource.propertiesFromSource(BasicPropertiesConfigSource.java:64) 3 at com.mchange.v2.cfg.BasicMulti

Storm java.io.FileNotFoundException: File &#39;../stormconf.ser&#39; does not exist

This bug will kill supervisors Affects Version/s: 0.9.2-incubating, 0.9.3, 0.9.4 Fix Version/s: 0.10.0, 0.9.5 问题背景 最近发现刚搭起的Storm集群,没过多久,Supervisor 便悄然死去了一大半.查看死去Supervisor的log,发现java.io.FileNotFoundException: File '../stormconf.ser' does not exist异常.

java.io.FileNotFoundException: class path resource [XXXXX.xml] cannot be opened

java.io.FileNotFoundException: class path resource [beans.xml] cannot be opened because it does not exit. 在用maven管理的spring项目中做单元测试时候,加载不了spring的配置文件.出现该问题的原因是,用maven创建的项目,必须把spring的配置文件beans.xml或者applicationContext.xml放到系统根目录下,做单元测试时候用 ApplicationCon

java.io.FileNotFoundException: class path resource ..cannot be opened because it does not exist

java.io.FileNotFoundException: class path resource ..cannot be opened because it does not exist 异常如下: java.io.FileNotFoundException: class path resource [com/jxust/zjh/model/Account.hbm.xml] cannot be opened because it does not exist 在spring中我这样配置<pr

freemarker报 java.io.FileNotFoundException:及TemplateLoader使用

使用过freemarker的肯定其见过如下情况: 1 java.io.FileNotFoundException: Template xxx.ftl not found. 模板找不到.可能你会认为我明明指定了文件,并且文件存在,但是为什么就是说找不到呢? 经过研究官方的API,原来freemarker在加载模板时,建议使用TemplateLoader,通过TemplateLoader指定从哪个目录开始加载模板,并且把模板加载在缓存中. API的TemplateLoader是一个接口,他有如下几个

解决 java.io.FileNotFoundException: class path resource [applicationContext.xml] cannot be opened because it does not exist

前几天好好运行的web项目突然跑不起来了 报这个错误 2019-09-16 19:18:29 [ RMI TCP Connection(3)-127.0.0.1:357 ] - [ ERROR ] Context initialization failed org.springframework.beans.factory.BeanDefinitionStoreException: IOException parsing XML document from class path resource

springboot多环境日志配置,启动时logback-test.xml文件冲突导致启动失败:openFile(null,true) call failed. java.io.FileNotFoundException

如题,在项目中用到了4个环境的日志配置文件,启动时在application.properties中指定环境,让springboot自动加载logback对应的配置文件: 每个环境的日志目录都不一样,比如sit和test环境分别是: 如果spring.profiles.active配置的是test,那么一切正常,非test环境,则启动失败.比如我现在配置spring.profiles.active=sit来启动联调环境,报错日志如下: 2020-01-10 14:32:33.579 |-ERROR