For each type of supported resource (CSS, Javascript, Binary [image, font, …]), you need an instance of net.jawr.web.servlet.JawrServlet running. Of course, you may choose to use Jawr for only one of these types of resources.
By default, all bundles are created and postprocessed when this servlet starts up and stored at the application server’s temporary directory. This way there is no processing overhead on requests, but you must remember to use the load-on-startup tag to force the Jawr servlet to initialize with your application server.
For every request, the servlet will make an attempt at forcing the client to keep a resource in cache for as long as possible using response headers. Also, if a request contains the If-Modified-Since header, the response status is set to 304(not modified) and no content is sent since such header means that the resource is already cached by the client.
Here is an example configuration of the servlet in a web.xml file:
<servlet> <servlet-name>JavascriptServlet</servlet-name> <servlet-class>net.jawr.web.servlet.JawrServlet</servlet-class> <init-param> <param-name>configLocation</param-name> <param-value>/jawr.properties</param-value> </init-param> <load-on-startup>1</load-on-startup> </servlet>
We would use this servlet to manage javascript bundles. The init params for a Jawr servlet are the following:
<servlet-mapping> <servlet-name>JavascriptServlet</servlet-name> <url-pattern>*.js</url-pattern> </servlet-mapping>
However, you might be forced to serve some of your scripts in the traditional way. For instance, you might be using a tag library that imports scripts on its own, or simply you want to update an existing application to use Jawr in some cases, but you don’t want to change each and every page. You can then use a mapping in the form of /jsJawrPath/*, so that all URLs created by the tag library start with this path mapping. You will then need to specify the mapping init param to let Jawr know about this so that URLs are properly formed. So if you map the servlet to /jsJawrPath/*, the mapping init param should have a value of /jsJawrPath/. The resulting configuration would end up like this:
... <servlet> <servlet-name>JavascriptServlet</servlet-name> <servlet-class>net.jawr.web.servlet.JawrServlet</servlet-class> <init-param> <param-name>configLocation</param-name> <param-value>/jawr.properties</param-value> </init-param> <init-param> <param-name>mapping</param-name> <param-value>/jsJawrPath/</param-value> </init-param> <load-on-startup>1</load-on-startup> </servlet> ... <servlet-mapping> <servlet-name>JavascriptServlet</servlet-name> <url-pattern>/jsJawrPath/*</url-pattern> </servlet-mapping>
Jawr supports binary web resources (images, fonts, …). To enable this feature, you will have to define the Jawr binary servlet in your web.xml file. When the Jawr binary servlet is defined in you application, all CSS images or fonts will be handled by this servlet.
In order for Jawr to properly handle the CSS images and fonts, the Jawr Binary servlet must start before the Jawr CSS servlet. This means that you will have to set properly the load.on.startup property in your web.xml like below :
... <servlet> <servlet-name>JawrBinaryServlet</servlet-name> <servlet-class>net.jawr.web.servlet.JawrServlet</servlet-class> <init-param> <param-name>configLocation</param-name> <param-value>/jawr.properties</param-value> </init-param> <init-param> <param-name>type</param-name> <param-value>binary</param-value> </init-param> <!-- The Jawr Binary servlet must start before the Jawr CSS Servlet --> <load-on-startup>0</load-on-startup> </servlet> <servlet> <servlet-name>JawrCSSServlet</servlet-name> <servlet-class>net.jawr.web.servlet.JawrServlet</servlet-class> <init-param> <param-name>configLocation</param-name> <param-value>/jawr.properties</param-value> </init-param> <init-param> <param-name>type</param-name> <param-value>css</param-value> </init-param> <load-on-startup>1</load-on-startup> </servlet> ... <!-- Images mapping --> <servlet-mapping> <servlet-name>JawrBinaryServlet</servlet-name> <url-pattern>*.png</url-pattern> </servlet-mapping> <servlet-mapping> <servlet-name>JawrBinaryServlet</servlet-name> <url-pattern>*.gif</url-pattern> </servlet-mapping> <!-- Fonts mapping --> <servlet-mapping> <servlet-name>JawrBinaryServlet</servlet-name> <url-pattern>*.woff</url-pattern> </servlet-mapping> <servlet-mapping> <servlet-name>JawrBinaryServlet</servlet-name> <url-pattern>*.ttf</url-pattern> </servlet-mapping> <servlet-mapping> <servlet-name>JawrBinaryServlet</servlet-name> <url-pattern>*.svg</url-pattern> </servlet-mapping> <servlet-mapping> <servlet-name>JawrBinaryServlet</servlet-name> <url-pattern>*.eot</url-pattern> </servlet-mapping> <!-- CSS mapping --> <servlet-mapping> <servlet-name>JawrCSSServlet</servlet-name> <url-pattern>*.css</url-pattern> </servlet-mapping>
Note : The declaration of your binary in the jawr.binary.resources property is not mandatory. This property is used to calculate the hashcode of the images at the image servlet startup. If a binary resource is not defined in this property, the hashcode of this resource will be calculated at runtime. Look for jawr.binary.resources at the descriptor syntax doc for more information.
<?xml version="1.0" encoding="ISO-8859-1"?> <!DOCTYPE web-app PUBLIC "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN" "http://java.sun.com/dtd/web-app_2_3.dtd"> <web-app> <display-name>Jawr enabled application</display-name> <description> </description> <servlet> <servlet-name>JavascriptServlet</servlet-name> <servlet-class>net.jawr.web.servlet.JawrServlet</servlet-class> <init-param> <param-name>configLocation</param-name> <param-value>/jawr.properties</param-value> </init-param> <load-on-startup>0</load-on-startup> </servlet> <servlet> <servlet-name>CssServlet</servlet-name> <servlet-class>net.jawr.web.servlet.JawrServlet</servlet-class> <init-param> <param-name>configLocation</param-name> <param-value>/jawr.properties</param-value> </init-param> <init-param> <param-name>type</param-name> <param-value>css</param-value> </init-param> <load-on-startup>1</load-on-startup> </servlet> <servlet-mapping> <servlet-name>JavascriptServlet</servlet-name> <url-pattern>*.js</url-pattern> </servlet-mapping> <servlet-mapping> <servlet-name>CssServlet</servlet-name> <url-pattern>*.css</url-pattern> </servlet-mapping> </web-app>
<?xml version="1.0" encoding="ISO-8859-1"?> <!DOCTYPE web-app PUBLIC "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN" "http://java.sun.com/dtd/web-app_2_3.dtd"> <web-app> <display-name>Jawr enabled application</display-name> <description> </description> <servlet> <servlet-name>JavascriptServlet</servlet-name> <servlet-class>net.jawr.web.servlet.JawrServlet</servlet-class> <init-param> <param-name>configLocation</param-name> <param-value>/jawr.properties</param-value> </init-param> <load-on-startup>0</load-on-startup> </servlet> <servlet> <servlet-name>JawrBinaryServlet</servlet-name> <servlet-class>net.jawr.web.servlet.JawrServlet</servlet-class> <init-param> <param-name>type</param-name> <param-value>binary</param-value> </init-param> <init-param> <param-name>configLocation</param-name> <param-value>/jawr.properties</param-value> </init-param> <!-- The Jawr Image servlet must start before the Jawr CSS Servlet --> <load-on-startup>0</load-on-startup> </servlet> <servlet> <servlet-name>CssServlet</servlet-name> <servlet-class>net.jawr.web.servlet.JawrServlet</servlet-class> <init-param> <param-name>configLocation</param-name> <param-value>/jawr.properties</param-value> </init-param> <init-param> <param-name>type</param-name> <param-value>css</param-value> </init-param> <load-on-startup>1</load-on-startup> </servlet> <servlet-mapping> <servlet-name>JavascriptServlet</servlet-name> <url-pattern>*.js</url-pattern> </servlet-mapping> <servlet-mapping> <servlet-name>CssServlet</servlet-name> <url-pattern>*.css</url-pattern> </servlet-mapping> <servlet-mapping> <servlet-name>JawrBinaryServlet</servlet-name> <url-pattern>*.png</url-pattern> </servlet-mapping> <servlet-mapping> <servlet-name>JawrBinaryServlet</servlet-name> <url-pattern>*.gif</url-pattern> </servlet-mapping> </web-app>
By default, Jawr use properties file as configuration file. Jawr allows users to use JSON configuration source by using the configPropertiesSourceClass init param. You can define the location of the configuration file by using the parameter configLocation. This implementation requires the Jackson JSON library. So you’ll have to add it to your classpath. For maven users, you’ll have to update your pom file to add the jackson dependencies.
Here is a sample of jackson dependency declaration in a pom.xml file :
... <dependency> <groupId>com.fasterxml.jackson.datatype</groupId> <artifactId>jackson-datatype-json-org</artifactId> <version>2.4.2</version> </dependency> ...
Here is an example of configuration :
<servlet> <servlet-name>JavascriptServlet</servlet-name> <servlet-class>net.jawr.web.servlet.JawrServlet</servlet-class> <init-param> <param-name>configPropertiesSourceClass</param-name> <param-value>net.jawr.web.resource.bundle.factory.util.JsonPropertiesSource</param-value> </init-param> <init-param> <param-name>configLocation</param-name> <param-value>/jawr.json</param-value> </init-param> <load-on-startup>1</load-on-startup> </servlet>
You can customize the way properties are loaded into Jawr, be it by reading data from a source other than a .properties file (like, say, a database), or simply by manually overriding some of the values from the properties file. To do that you must create an implementation of the interface net.jawr.web.resource.bundle.factory.util.ConfigPropertiesSource and then you must declare it when defining the Jawr servlet, by setting the configPropertiesSourceClass init param:
<servlet> <servlet-name>JavascriptServlet</servlet-name> <servlet-class>net.jawr.web.servlet.JawrServlet</servlet-class> <init-param> <param-name>configPropertiesSourceClass</param-name> <param-value>com.mycompany.mypackage.MyConfigPropertiesSourceImplementation</param-value> </init-param> <load-on-startup>1</load-on-startup> </servlet>
The ConfigPropertiesSource interface declares two methods:
/** * Read/modify configuration from a source (such as a .properties file) and return it. * @return */ public abstract Properties getConfigProperties(); /** * Determine if configuration is changed to reconfigure Jawr during development * without having to restart the server. * @return */ public abstract boolean configChanged();
The configChanged method will be called only if you set the jawr.config.reload.interval parameter in the properties file to any valid value. This would have Jawr check every n seconds whether configuration has changed since the last time it was loaded. Therefore, if configChanged returns true, Jawr will redeploy itself.
If you only intend to override some values of the properties file for some reason (like mapping the debug mode to some global property from your own application), the best way to go is to subclass net.jawr.web.resource.bundle.factory.util.PropsFilePropertiesSource. Check the javadoc for details.
By default no ConfigPropertyResolver is used in Jawr, but you can customize the way properties are resolved in Jawr.
The property resolver is used to resolve values from placeholder, which are like “\${myValueToReplace}”. To do that you must create an implementation of the interface net.jawr.web.config.ConfigPropertyResolver and then you must declare it when defining the Jawr servlet, by setting the configPropertyResolverClass init param:
<servlet> <servlet-name>JavascriptServlet</servlet-name> <servlet-class>net.jawr.web.servlet.JawrServlet</servlet-class> <init-param> <param-name>configPropertyResolverClass</param-name> <param-value>com.mycompany.mypackage.MyConfigPropertyResolverImplementation</param-value> </init-param> <load-on-startup>1</load-on-startup> </servlet>
The ConfigPropertyResolver interface declares one method:
/** * Resolve the property. If the property has not been resolved <b>null</b> should be return * @param property the property to resolve * @return the property value or null if not resolved */ public String resolve(String property);
Jawr provides a built-in System property resolver which will find the value of the properties in the System Property.
To use this property resolver, you need to configure your servlet as below :
<servlet> <servlet-name>JavascriptServlet</servlet-name> <servlet-class>net.jawr.web.servlet.JawrServlet</servlet-class> <init-param> <param-name>configPropertyResolverClass</param-name> <param-value>net.jawr.web.config.ConfigSystemPropertyResolver</param-value> </init-param> <load-on-startup>1</load-on-startup> </servlet>