Portable extensions that make JSF nicer to use.
Sometime back I had blogged about how you can render a pretty URL for JSF resources which are local to the web-app. I have successfully used this technique across various pet projects of mine, but the repetition was definitely annoying me. So I decided to put together a portable JSF extension that can be easily included in to any project.
Additionally, I also realized that when consuming an open-source CSS library, I find myself rewriting the relative URL references to fit the JSF resource handling format, i.e., something on the below lines,
url("#{resource['bootstrap:fonts/glyphicons-halflings-regular.eot']}");
This task can make upgrades quite tedious, so I figured I should be able to leverage existing constructs to solve this problem instead of defining new ones.
Consider the following project layout,
├── app
│ └── src
│ └── main
│ └── webapp
│ ├── index.xhtml
│ └── resources
│ └── popper
│ └── js
│ ├── popper.js ∖ Resources local
│ └── popper.min.js / to the web-app
├── resource-library
│ └── src
│ └── main/resources/
│ └── META-INF/resources
│ ├── bootstrap
│ │ ├── css
│ │ │ ├── bootstrap.css
│ │ │ ├── bootstrap.min.css
│ │ ├── js
│ │ │ ├── bootstrap.js
│ │ │ ├── bootstrap.min.js
│ │ └── v_4.0.0
│ └── open-iconic
│ ├── css
│ │ ├── open-iconic-bootstrap.css ∖__
│ │ ├── open-iconic-bootstrap.min.css / |
│ ├── fonts |
│ │ ├── open-iconic.eot ∖ |
│ │ ├── open-iconic.otf | Uses relative
│ │ ├── open-iconic.svg |<---- URL references
│ │ ├── open-iconic.ttf | to point to these
│ │ └── open-iconic.woff / files
│ └── v_1.1.0
, and let's say your index.xhtml
has the following resource declarations,
...
<h:outputStylesheet library="bootstrap" name="css/bootstrap.min.css"/>
<h:outputStylesheet library="open-iconic" name="css/open-iconic-bootstrap.min.css"/>
...
<script src="https://code.jquery.com/jquery-3.2.1.slim.min.js" crossorigin="anonymous"/>
<h:outputScript library="popper" name="js/popper.min.js" crossorigin="anonymous"/>
<h:outputScript library="bootstrap" name="js/bootstrap.min.js" crossorigin="anonymous"/>
...
, the final rendered output might look like the below,
<link type="text/css" rel="stylesheet" href="/javax.faces.resource/css/bootstrap.min.css.xhtml?ln=bootstrap"/>
<link type="text/css" rel="stylesheet" href="/javax.faces.resource/css/open-iconic-bootstrap.min.css.xhtml?ln=open-iconic"/>
<script src="https://code.jquery.com/jquery-3.2.1.slim.min.js" crossorigin="anonymous"/>
<script type="text/javascript" src="/javax.faces.resource/js/popper.min.js.xhtml?ln=popper"/>
<script type="text/javascript" src="/javax.faces.resource/js/bootstrap.min.js.xhtml?ln=bootstrap"/>
The problem with the above rendering is that the Open-Iconic file would request for the CSS files that translate to,
<link type="text/css" rel="stylesheet" href="/javax.faces.resource/fonts/open-iconic.eot?"/>
Now, the JSF resource servlet (which would handle the above request) will not know how to handle this request .. and it returns a 404!
And this is where my library will help you. Here is what it does,
- If a resource is local to your web-app, then do not bother rendering it via the JSF servlet.
- If a request comes in for a resource that does not have any library name associated (e.g., the 404 case noted above), then look for the referrer URL and determine the library details from it and send a redirect to the correct resource URL.
Once you include this project as a dependency, then you will notice that rendered URLs look like the following,
<link type="text/css" rel="stylesheet" href="/javax.faces.resource/css/bootstrap.min.css.xhtml?ln=bootstrap"/>
<link type="text/css" rel="stylesheet" href="/javax.faces.resource/css/open-iconic-bootstrap.min.css.xhtml?ln=open-iconic"/>
<script src="https://code.jquery.com/jquery-3.2.1.slim.min.js" crossorigin="anonymous"/>
<script type="text/javascript" src="/resources/popper/js/popper.min.js"/>
<script type="text/javascript" src="/javax.faces.resource/js/bootstrap.min.js.xhtml?ln=bootstrap"/>
And the RelativeResourceHandlingFilter will take care of sending the appropriate redirect to the browser.
- Java 8
- JavaEE 7 - specifically JSF2
This module is published to OSS Central and can be access at the following coordinates:
io.rogue.ee:jsf-extensions:<version>
Check the following link for locating the latest version.
https://oss.sonatype.org/#nexus-search;gav~io.rogue.ee~jsf-extensions~~~
The very initial functioning release is version 0.0.0
Branch | Status |
---|---|
master | |
develop |