What is wro4j

Since you are here, you most likely know, but for others. wro4j (Web Resource Optimizer for Java) allows you (as name suggests) to optimize your web resources. Typically when you build (rich) web application you use several CSS/JS frameworks and develop additional CSS/JS of your own. And all of this needs to be downloaded to browser. That is not typically big problem for desktops with broad-band internet, but in era of mobile internet it is very helpful if you can bundle all of this to few HTTP requests that download everything needed together and in addition minimize and gzip the content (e.g. by removing your comments from JS).

wro4j can work in two modes – runtime and compile time. You can do all this magic compile time and just use results in your JAR/WAR. This has clear benefits (like no runtime dependency on wro4j, no runtime “compilation” etc) but also the setup was more complicated, you need to properly configure your IDE to “hot” recompile your resources as you are developing and you need to configure some features by yourself (e.g. caching/gzip). So for now I decided to use runtime setup with wro http filter.

Spring Boot setup

wro4j itself does not have spring boot support, nor spring boot can autoconfigure it. I have found 3rd party library for that but I didn’t want to add additional maven repository just for that. Additionally I don’t like that is support only “pre-selected” configuration options (although the most used are there). Therefore I decided to configure it myself.

So first you need to add wro4j as dependency to your project (in my case maven):

		<!-- wro4j -->
		<dependency>
			<groupId>ro.isdc.wro4j</groupId>
			<artifactId>wro4j-core</artifactId>
			<version>1.7.8</version>
		</dependency>
		<dependency>
			<groupId>ro.isdc.wro4j</groupId>
			<artifactId>wro4j-extensions</artifactId>
			<version>1.7.8</version>
		</dependency>

Then we need to configure wro4j filter in one of your @Configuration classes.

	@Bean
	FilterRegistrationBean webResourceOptimizer(Environment env) {
		FilterRegistrationBean fr = new FilterRegistrationBean();
		ConfigurableWroFilter filter = new ConfigurableWroFilter();
		filter.setProperties(buildWroProperties(env));
		fr.setFilter(filter);
		fr.addUrlPatterns("/wro/*");
		return fr;
	}

	private static final String[] OTHER_WRO_PROP = new String[] { ConfigurableProcessorsFactory.PARAM_PRE_PROCESSORS,
			ConfigurableProcessorsFactory.PARAM_POST_PROCESSORS };

	private Properties buildWroProperties(Environment env) {
		Properties prop = new Properties();
		for (ConfigConstants c : ConfigConstants.values()) {
			addProperty(env, prop, c.name());
		}
		for (String name : OTHER_WRO_PROP) {
			addProperty(env, prop, name);
		}
		log.debug("Wro4J properties {}", prop);
		return prop;
	}

	private void addProperty(Environment env, Properties to, String name) {
		String value = env.getProperty("wro." + name);
		if (value != null) {
			to.put(name, value);
		}
	}

As you can see from code, it register filter to /wro/* path and reads all properties from your application.properties (or alternative) with “wro.” prefix. Unfortunately not all wro properties are part of ro.isdc.wro.config.jmx.ConfigConstants, so if you need anything else, just extend OTHER_WRO_PROP.

All what’s left is to “use” wro4j – create your wro.xml in WEB-INF directory

<?xml version="1.0" encoding="UTF-8"?>
<groups xmlns="http://www.isdc.ro/wro">

    <group name="other">
        <js>classpath:static/jquery/jquery-1.10.1.min.js</js>
        <js>classpath:static/timeago/jquery.timeago.1.4.1.js</js>
        <css>classpath:static/slider/slider.css</css>
    </group>
    
</groups>

and setup your application.properties as you want.

# wro4j config
wro.preProcessors=cssUrlRewriting,cssImport,semicolonAppender,lessCss
wro.postProcessors=cssVariables,cssMinJawr,jsMin
# set to 1 second to check for resource changes
wro.resourceWatcherUpdatePeriod = 0
wro.ignoreMissingResources = false

Enjoy.

Update: If you are not deploying .war file, you need to override where wro.xml comes from. Check this sample project

Related Post

4 Comments

Leave a Reply to Pete Storey Cancel reply

© 2021 Instea, s.r.o.
All rights reserved.

Contact us

Where to find us