smeeb
smeeb

Reputation: 29477

Dropwizard Assets not serving static content outside of root path

Here's my Dropwizard (0.8.5) app's basic project structure:

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

Where the gist of each of those classes is:

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>

So you can see I'm using DW as an actual web app/UI, and that I'm utilizing both Dropwizard Views (Freemarker binding) as well as Dropwizard Assets.

When I run this, the app starts up just fine and I am able to visit both my homepage (served from / which maps to index.ftl) as well as my dashboard page (served from /app/dashboard which maps to dashboard.ftl).

The problem is that both pages use the header.ftl, which pulls in my assets/images/mylogo.png, but only my homepage actually renders the logo. On my dashboard page, I do see the "This is the header!" message, so I know the header is being resolved and included with my dashboard template. But, I get a failed-to-load-image "X" icon, and when I open my browser's dev tools I see that I'm getting HTTP 404s on the image.

So it seems that DW is unable to find my image asset from a view/URL not directly living under root (/).

On the Dropwizard Assets page (link provided above) there's a peculiar warning:

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.

I don't entirely understand what this means, but suspect it is the main culprit here. Either way, anyone see where I'm going awry, and what I can do (exact steps!) to fix this?

Upvotes: 0

Views: 1118

Answers (2)

Johnathon Havens
Johnathon Havens

Reputation: 730

You need to add / before your URI:

<img src="/images/mylogo.png" />

this can be explained from the examples in RFC 3986 URI Generic Syntax, I pulled out the relevant examples.

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"

Putting in the preceding / makes the URI begin from the domain name regardless of the referring URI, which allows you to do precisely what you want.

Upvotes: 2

nightowl.engineer
nightowl.engineer

Reputation: 329

Load both pages up (the one that works, and the one that doesn't), and use Firebug or Chrome dev tools to inspect the logo element. What path is it trying to get to? I suspect on your index page it's going to http://some.thing/images/mylogo.png whereas on your dashboard it's trying to load http://some.thing/app/dashboard/images/mylogo.png

Try putting an additional / in front of the path in your template, and it should resolve from anywhere.

(Originally answered here: Dropwizard-user Google Group)

Upvotes: 1

Related Questions