Dropwizard Assets 不提供根路径之外的静态内容
Dropwizard Assets not serving static content outside of root path
这是我的 Dropwizard (0.8.5) 应用程序的基本项目结构:
myapp/
src/main/groovy/
org/example/myapp/
MyApp.groovy
<lots of other packages/classes>
controllers/
site/
SiteController.groovy
dashboard/
DashboardController.groovy
org/example/myapp/views
site/
SiteView.groovy
dashboard/
DashboardView.groovy
src/main/resources/
assets/
images/
mylogo.png
org/example/myapp/views/
site/
header.ftl
index.ftl
dashboard/
dashboard.ftl
每个 类 的要点是:
class MyApp extends Application<MyAppConfiguration> {
@Override
void initialize(Bootstrap<MyAppConfiguration> bootstrap) {
bootstrap.addBundle(new AssetsBundle('/assets/images', '/images', null, 'images'))
bootstrap.addBundle(new ViewBundle())
}
// etc...
}
@Path('/')
@Produces('text/html')
class SiteController {
@GET
SiteView homepage() {
new SiteView()
}
}
@Path('/app/dashboard')
@Produces('text/html')
class DashboardController {
@GET
DashboardView dashboard() {
new DashboardView()
}
}
header.ftl (dropwizard-views-freemarker)
=========================================
<!DOCTYPE html>
<html>
<head> <!-- lots of stuff omitted here for brevity --> </head>
<body>
<div class="well">
<img src="images/mylogo.png" />
<br/>This is the header!
</div>
index.ftl
=========
<#include "header.ftl">
<p>
Homepage!
</p>
</body>
</html>
dashboard.ftl
=============
<#include "../site/header.ftl">
<p>
Dashboard!
</p>
</body>
</html>
所以你可以看到我将 DW 用作实际的网络 app/UI,并且我正在利用两者 Dropwizard Views (Freemarker binding) as well as Dropwizard Assets。
当我 运行 这样做时,应用程序启动正常,我可以访问我的主页(从映射到 index.ftl
的 /
提供)以及我的主页仪表板页面(从映射到 dashboard.ftl
的 /app/dashboard
提供)。
问题是两个页面都使用了 header.ftl
,它拉入了我的 assets/images/mylogo.png
,但实际上只有我的主页呈现了徽标。 在我的仪表板页面,我 do 看到“This is the header!”消息,所以我知道 header 是正在解决并包含在我的仪表板模板中。 但是,我得到一个 failed-to-load-image "X" 图标,当我打开浏览器的开发工具时,我看到我在图像上收到 HTTP 404。
所以 DW 似乎无法从 view/URL 中找到我的图像资产,而不是直接生活在 root 下(/
)。
在 Dropwizard 资产页面(link 上面提供的)有一个特殊的警告:
Either your application or your static assets can be served from the root path, but not both. The latter is useful when using Dropwizard to back a Javascript application. To enable it, move your application to a sub-URL.
我不完全明白这是什么意思,但怀疑它是这里的罪魁祸首。无论哪种方式,有人看到我哪里出了问题,以及我可以做什么(具体步骤!)来解决这个问题?
加载两个页面(一个有效,一个无效),并使用 Firebug 或 Chrome 开发工具检查徽标元素。它试图到达什么路径?我怀疑在您的索引页上它会 http://some.thing/images/mylogo.png whereas on your dashboard it's trying to load http://some.thing/app/dashboard/images/mylogo.png
尝试在模板中的路径前添加一个 /,它应该可以从任何地方解析。
(最初在这里回答:Dropwizard-user Google Group)
您需要在您的 URI 前添加 /:
<img src="/images/mylogo.png" />
这个可以从RFC 3986 URI Generic Syntax中的例子中得到解释,我把相关的例子拉出来了
5.4. Reference Resolution Examples
Within a representation with a well defined base URI of
http://a/b/c/d;p?q
a relative reference is transformed to its target URI as follows.
5.4.1. Normal Examples
"g" = "http://a/b/c/g"
"g/" = "http://a/b/c/g/"
"/g" = "http://a/g"
"../g" = "http://a/b/g"
"../../g" = "http://a/g"
不管引用的 URI 是什么,在前面加上 / 都会使 URI 从域名开始,这样您就可以精确地执行您想要的操作。
这是我的 Dropwizard (0.8.5) 应用程序的基本项目结构:
myapp/
src/main/groovy/
org/example/myapp/
MyApp.groovy
<lots of other packages/classes>
controllers/
site/
SiteController.groovy
dashboard/
DashboardController.groovy
org/example/myapp/views
site/
SiteView.groovy
dashboard/
DashboardView.groovy
src/main/resources/
assets/
images/
mylogo.png
org/example/myapp/views/
site/
header.ftl
index.ftl
dashboard/
dashboard.ftl
每个 类 的要点是:
class MyApp extends Application<MyAppConfiguration> {
@Override
void initialize(Bootstrap<MyAppConfiguration> bootstrap) {
bootstrap.addBundle(new AssetsBundle('/assets/images', '/images', null, 'images'))
bootstrap.addBundle(new ViewBundle())
}
// etc...
}
@Path('/')
@Produces('text/html')
class SiteController {
@GET
SiteView homepage() {
new SiteView()
}
}
@Path('/app/dashboard')
@Produces('text/html')
class DashboardController {
@GET
DashboardView dashboard() {
new DashboardView()
}
}
header.ftl (dropwizard-views-freemarker)
=========================================
<!DOCTYPE html>
<html>
<head> <!-- lots of stuff omitted here for brevity --> </head>
<body>
<div class="well">
<img src="images/mylogo.png" />
<br/>This is the header!
</div>
index.ftl
=========
<#include "header.ftl">
<p>
Homepage!
</p>
</body>
</html>
dashboard.ftl
=============
<#include "../site/header.ftl">
<p>
Dashboard!
</p>
</body>
</html>
所以你可以看到我将 DW 用作实际的网络 app/UI,并且我正在利用两者 Dropwizard Views (Freemarker binding) as well as Dropwizard Assets。
当我 运行 这样做时,应用程序启动正常,我可以访问我的主页(从映射到 index.ftl
的 /
提供)以及我的主页仪表板页面(从映射到 dashboard.ftl
的 /app/dashboard
提供)。
问题是两个页面都使用了 header.ftl
,它拉入了我的 assets/images/mylogo.png
,但实际上只有我的主页呈现了徽标。 在我的仪表板页面,我 do 看到“This is the header!”消息,所以我知道 header 是正在解决并包含在我的仪表板模板中。 但是,我得到一个 failed-to-load-image "X" 图标,当我打开浏览器的开发工具时,我看到我在图像上收到 HTTP 404。
所以 DW 似乎无法从 view/URL 中找到我的图像资产,而不是直接生活在 root 下(/
)。
在 Dropwizard 资产页面(link 上面提供的)有一个特殊的警告:
Either your application or your static assets can be served from the root path, but not both. The latter is useful when using Dropwizard to back a Javascript application. To enable it, move your application to a sub-URL.
我不完全明白这是什么意思,但怀疑它是这里的罪魁祸首。无论哪种方式,有人看到我哪里出了问题,以及我可以做什么(具体步骤!)来解决这个问题?
加载两个页面(一个有效,一个无效),并使用 Firebug 或 Chrome 开发工具检查徽标元素。它试图到达什么路径?我怀疑在您的索引页上它会 http://some.thing/images/mylogo.png whereas on your dashboard it's trying to load http://some.thing/app/dashboard/images/mylogo.png
尝试在模板中的路径前添加一个 /,它应该可以从任何地方解析。
(最初在这里回答:Dropwizard-user Google Group)
您需要在您的 URI 前添加 /:
<img src="/images/mylogo.png" />
这个可以从RFC 3986 URI Generic Syntax中的例子中得到解释,我把相关的例子拉出来了
5.4. Reference Resolution Examples
Within a representation with a well defined base URI of
http://a/b/c/d;p?q
a relative reference is transformed to its target URI as follows.
5.4.1. Normal Examples
"g" = "http://a/b/c/g"
"g/" = "http://a/b/c/g/"
"/g" = "http://a/g"
"../g" = "http://a/b/g"
"../../g" = "http://a/g"
不管引用的 URI 是什么,在前面加上 / 都会使 URI 从域名开始,这样您就可以精确地执行您想要的操作。