JBoss Web App

To serve both web apps and servlets, JBoss uses:

  • EAP 6.x: Tomcat
  • EAP 7.x & Wildfly: Undertow

Tomcat

JBossWeb Rewrite Valve (EAP 6.x)

With gratitude to RedHat's Arron Ogburg...

This works in EAP >= 6.4.8. Within jboss-web.xml:

...
<subsystem xmlns="urn:jboss:domain:web:1.1" default-virtual-server="default-host" native="false">
    <connector name="http" protocol="HTTP/1.1" scheme="http" socket-binding="http"/>
      <virtual-server name="default-host" enable-welcome-root="false">
        <alias name="localhost"/>
        <alias name="example.com"/>
        <rewrite name="rule-1" pattern="^/(.*)" substitution="/index.html" flags="RL">
          <condition name="condition-1" test="%{REQUEST_PATH}" pattern="!-s"/>
        </rewrite>
    </virtual-server>
</subsystem>
...

Tuckey UrlRewriteFilter

Adding the Tuckey UrlRewriteFilter into your application's war provides the desired rewrite behavior.

[Tuckey UrlRewriteFilter is a]... Java Web Filter for any compliant web application server (such as Tomcat, JBoss, Jetty or Resin), which allows you to rewrite URLs before they get to your code. It is a powerful tool just like Apache's mod_rewrite.

To install the UrlRewriteFilter:

  1. Add the following dependency:

    • Maven
    <dependency>
     <groupId>org.tuckey</groupId>
     <artifactId>urlrewritefilter</artifactId>
     <version>4.0.3</version>
    </dependency>
    
    • Gradle
    compile group: 'org.tuckey', name: 'urlrewritefilter', version: '4.0.3'
    
  2. To WEB-INF/web.xml (download web.xml) add:

    <filter>
        <filter-name>UrlRewriteFilter</filter-name>
        <filter-class>org.tuckey.web.filters.urlrewrite.UrlRewriteFilter</filter-class>
        <!-- For rule debugging to the console log -->
        <!--<init-param>-->
            <!--<param-name>logLevel</param-name>-->
            <!--<param-value>TRACE</param-value>-->
        <!--</init-param>-->
    </filter>

    <filter-mapping>
        <filter-name>UrlRewriteFilter</filter-name>
        <url-pattern>/*</url-pattern>
        <dispatcher>REQUEST</dispatcher>
        <dispatcher>FORWARD</dispatcher>
    </filter-mapping>
  1. Add the file WEB-INF/urlrewrite.xml (download urlrewrite.xml) add one of the following rules, which ever seems more natural:

    • Regex-based
     <rule match-type="regex">
         <name>Client Routes</name>
         <note>For all routes that are not file requests, forward to index.html.</note>
         <condition type="request-uri" operator="notequal">^\/([\-\w\.]+)([\-/\w\.]*)(\.([\-\w]+))$</condition>
         <from>^\/([/\-\w]+)$</from>
         <to type="forward" last="true">/index.html</to>
     </rule>
    
    • Wildcard-based
     <rule match-type="regex">
         <name>Client Routes</name>
         <note>For all routes that are not file requests, forward to index.html.</note>
         <condition type="request-uri" operator="notequal">^\/([\-\w\.]+)([\-/\w\.]*)(\.([\-\w]+))$</condition>
         <from>^\/([/\-\w]+)$</from>
         <to type="forward" last="true">/index.html</to>
     </rule>
    

Using Both JBossWeb Rewrite Valve & UrlRewriteFilter in Same App

You can use JBossWeb Rewrite Valve to put the app in HTML5 mode and UrlRewriteFilter for other rewrite handling. The JBossWeb Rewrite Valve takes precedence.

UrlRewriteFilter is implemented as a standard servlet filter that can redirect and forward requests. A request will be processed by JBossWeb valves first before servlet filter processing. Request operation is as follows:

  • The JBossWeb rewrite valve sees the requested file doesn't exist so it redirects the request and no other processing is done by the UrlRewriteFilter or app code.
  • The JBossWeb rewrite valve sees the requested file does exist so it passes the request through untouched. The request is processed by the UrlRewriteFilter, which either redirects/forwards it elsewhere or passes it through untouched to the app code to be served.

Undertow (EAP 7.x)

EAP JBoss 7.x (and Wildfly) has upgraded it's web server to use Undertow. Undertow is a fork of Tomcat that provides both blocking and non-blocking API’s based on Java NIO. Follow this examle to configure Undertow for 'HTML5 mode':

There are two rewrite options provided. The first is a succinct configuration that does not work due to noted issues. There are two, a Wildfly and an EAP:

  1. https://issues.jboss.org/browse/JBEAP-4846 (EAP 7.x)
  2. https://issues.jboss.org/browse/WFLY-6667 (Wildfly)

Check the status of those issues to use this filter, again, with gratitude to RedHat's Arron Ogburg:

Example 1

Create a WEB-INF/undertow-handlers.conf file with the following:

not file(%U) -> redirect('/index.html')

Example 2

This assumes that:

  • Our context path is '/'; don't rewrite '/'.
  • Our ReactJS application lives at /index.html; ; don't rewrite /index.html.
  • Rewrite everything else to index.html

The predicate that conforms with the example we’ve outlined above results in:

not equals[%R, '/'] and
not equals[%R, '/index.html'] and
regex['/.+'] -> rewrite['/km/index.html']

A hit on /foo/bar/ will resolve to our ReactJS app running at /index.html.

Place the above rules (sans linefeeds) into WEB-INF/undertow-handlers.conf.

The above configuration was obtained from a post dealing with routing within Angular. In this respect, ReactJS and Angular have a shared interest.