UrlMappings to point a URL to an asset pipeline fi

2019-04-07 00:52发布

问题:

In Grails 3.0 how do you map a URL to a file under the assets folder?

For example:
http://localhost:8080/favicon.ico --> grails-app/assets/images/bookmark.ico

I've tried a few test mappings, such as:

grails-app/controllers/UrlMappings.groovy

class UrlMappings {

   static mappings = {
      ...
      "/t1.png"  (uri: "/assets/images/test.png")
      "/t2.png"  (uri: "/assets/test.png")
      "/t3.png"  (uri: "/images/test.png")
      "/t4.png"  (dir: "assets/images", file: "test.png")
      ...
      }

}

...but they all result in a 500 server error.

回答1:

If you are not using the Asset-Pipeline you can map static resources to URLs by following the steps laid out in the Grails Documentation. However your question is asking how to map a single resource to a single URL with the Asset-Pipeline plugin.

Burt Beckwith provided insight on the Grails forum a few years ago about Grail's role in serving static resources.

Grails doesn't serve static resources, the container does. So there's no way to directly configure a mapping - you need to serve it through a controller or configure a proxy as Eric suggests.

Burt

This answer may be unsatisfying. But if you must serve a static resource and absolutely do not want to use a controller or proxy you can try the following.

Create a view called image.gsp. The view will only contain an asset tag. Using your examples above,

<asset:image src="t1.png"/>

Then configure your URL mappings to point to the image.gsp page.

class UrlMappings {

   static mappings = {
      ...
      "/t1.png"  (view: "image")
      ...
      }

}

I recognize this may not be the exact method you were hoping to use. But I think that understanding the role Grails plays vs. the container running Grails will help inform a decision to properly serve a resource to the user.

I know this may seem unrelated but if you want to create a page that lists the contents of a directory check out this post by CodePanda. His code can be used as a template to create a controller to serve a single file and he explains how to update the view, controller, and groovy.config.



回答2:

I think you need to map the URL to AssetController of the Asset Plugin, like this (not tested):

class UrlMappings {
    static mappings = {

    ...

    "/files/$id"  (controller :"AssetController", action:"index") 
       ...
    }
}

HTH



回答3:

Here is what I used to serve up swfobject.js at a specific URI:

Add a url mapping:

"/swf/swfobject.js" (controller:"facerecorder", action:"swfobject")

Add an action to the controller that locates the resource and serves it. Note that the assetResourceLocator, which is part of the asset pipeline, is injected into the controller.

class FacerecorderController {

    def assetResourceLocator

    def swfobject() {
        def resource = assetResourceLocator.findAssetForURI('swf/swfobject.js')
        render file: resource.inputStream, contentType: 'text/javascript' 
    }
}

It's definitely not ideal, but it works. Tested using Grails 3.0.17



回答4:

Using "/favicon.ico"(uri: "/assets/favicon.ico") works for me.

Conceptually, it appears that Asset Pipeline flattens the assets (so that you do not need to specity images, javascripts, stylesheets for the uri)

Grails: 3.2.11 AssetPipeline: 2.14.6