1

Facing poor documentation and guides on Internet about how to prettify routes in Java EE/Jakarta EE (version 7 or 8). I want to ask you people if you have any recommendations.

I am currently using OCPsoft Rewrite, but their documentation, guides and their community look really light or silent.

What do you do to transform the basic XHTML JSF routes to the views like views/mypage.xhtml into some beautiful URL like /path/to/mypage ?

Or maybe lots of people in Java EE/Jakarta EE, do not care about prettifying the routes ?

robinvrd
  • 1,760
  • 12
  • 28
  • So, essentially you don't want to "just get rid of .xhtml extension", but really a full fledged URL rewriting solution which can go through all paths? Because otherwise there are indeed much simpler solutions. – BalusC Feb 25 '19 at 19:00
  • I am really looking for more that just get rid of extension files and yes, having a full configurable way to rewrite my URLs. – robinvrd Feb 26 '19 at 08:17

1 Answers1

2

The rewrite filter (PrettyFaces) is one of the most commonly used filters. In fact, it's so common that we are actually briefly covering it here in the web applications course at Chalmers since a few years back. To use it, you first need the following dependencies added to your POM file;

<dependency>
    <groupId>org.ocpsoft.rewrite</groupId>
    <artifactId>rewrite-servlet</artifactId>
    <version>3.4.2.Final</version>
</dependency>
<dependency>
    <groupId>org.ocpsoft.rewrite</groupId>
    <artifactId>rewrite-config-prettyfaces</artifactId>
    <version>3.4.2.Final</version>
</dependency>

PrettyFaces fully uses JavaEE runtime annotations - so it should be available for use once you add it. Next, you define the configuration - by default it will look for a pretty-config.xml file inside your WEB-INF/ directory. A basic setup can look something like this;

<?xml version="1.0" encoding="UTF-8"?>
<pretty-config xmlns="http://ocpsoft.org/schema/rewrite-config-prettyfaces" 
               xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
               xsi:schemaLocation="http://ocpsoft.org/schema/rewrite-config-prettyfaces
               http://ocpsoft.org/xml/ns/prettyfaces/rewrite-config-prettyfaces.xsd">         
    <url-mapping id="home"> 
        <pattern value="/" /> 
        <view-id value="/index.xhtml" />
    </url-mapping> 
    <url-mapping id="view-authors">
        <pattern value="/authors" />
        <view-id value="/author/list.xhtml" />
    </url-mapping>
    <url-mapping id="delete-author">
        <pattern value="/authors/delete/#{id}"/> 
        <view-id value="/author/delete.xhtml?id=#{id}" />
    </url-mapping>
    <url-mapping id="edit-author">
        <pattern value="/authors/edit/#{id}"/> 
        <view-id value="/author/edit.xhtml?id=#{id}" />
    </url-mapping>    
</pretty-config>    

In essence you can read the above as make the view-id accessible as specified in pattern. To read the id value you specify the following on your pages (just like you normally would);

<f:metadata>
    <f:viewParam name="id" value="#{bean.id}" />
</f:metadata>

Since some time back, PrettyFaces also supports annotations - allowing you to skip the `pretty-config.xml" file and directly specify your alternate URL pattern on top of the backing bean class. Allowing you to do something like this directly in you backing bean;

@URLMapping(pattern = "/authors/edit/#{id}", viewId = "/author/edit.xhtml?id=#{id}")

You can find more information on these annotations here; https://www.ocpsoft.org/prettyfaces/annotations-support-is-coming-to-prettyfaces-url-rewriting/

While PrettyFaces allows you to control the full structure of the URL (including parameters), if you only need to strip the extension, you can use the OmniFaces ExtensionlessURL filter (http://showcase.omnifaces.org/facesviews/ExtensionlessURLs) - which simply is controlled like this;

<context-param>
    <param-name>org.omnifaces.FACES_VIEWS_SCAN_PATHS</param-name>
    <param-value>/*.xhtml</param-value>
</context-param>

This would make views accesible directly without the xhtml extension. To add OmniFaces to your project, just specify the following in your POM;

<dependency>
    <groupId>org.omnifaces</groupId>
    <artifactId>omnifaces</artifactId>
    <version>3.2</version>
</dependency>

I also like to mention that in the field (among implementations), it's not all that uncommon that applications roll their own solution and implement "prettification" on their own - this is especially common when applications need to "generate" their own URL based on some random ID. This can be done by implementing a custom filter that invokes forward() on the request dispatcher. This obviously allows you to take it even further and do pretty much whatever you want. Of course, you can really just use PrettyFaces - but I guess some people just like to go that extra step.

Sorry for the drawn out post, but I was unable to find a good, thorough coverage on this on the site - so I thought I might as well write one up.

Adam Waldenberg
  • 2,271
  • 9
  • 26
  • Thank you for all these explanations ! I stay confident in my choice of using OCPsoft tools, but you only talk about `pretty-faces` and not about rewrite engine. As I need to save an URL variable in the cookies before I see a page (to save values accross different containers in a cluster), I am currently using the `performHttp()` function of the `@RewriteConfiguration` file of Rewrite. Is it any thing like this more simple with Pretty Faces ? I moved from Pretty Faces to Rewrite for this reason. – robinvrd Feb 26 '19 at 08:21
  • Another question, is there any known compatibily issues with these tools and Java EE 8 ? – robinvrd Feb 26 '19 at 08:26
  • I focus on PrettyFaces because the question asks how prettification is usually done - you didn't mention that you also need to save the generated URL. The rewrite engine gives you some extra control - personally though, I have very seldomly needed to use it - PrettyFaces is definetly the easier solution. With that said, if you want to save the generated URL using a @RewriteConfiguration is one way to go. Another would be to write a filter that is matched against the generated URL and save the URL there. JavaEE 8 should not give you any problems. I am not aware of any compatibility issues. – Adam Waldenberg Feb 26 '19 at 08:51
  • Having clustered web apps and needed to store some search filters all over my website (so accross different web modules/containers/wars), I am currently using cookies and @RewriteConfiguration to save value in cookie and retrieve in when I am displaying a page on a different web containers of the cluster, does it make sense to you to do it that way ? – robinvrd Feb 26 '19 at 08:56
  • This would be a different question altogether. It really depends on your requirements. While storing this data in a cookie definetly works, I would maybe opt to store it in a database - the advantage being that it can be shared between users. But again, it depends on what your requirements are and how you intend to use this long-term. – Adam Waldenberg Feb 26 '19 at 09:03
  • Thank you for all the answers ! – robinvrd Feb 26 '19 at 09:06