human readable URLs in Oracle APEX – Part 3

In the first two parts of this blogpost series we covered the basics and the technique on how to provide nice/friendly/readable URLs for a public APEX Application.

If you haven’t read the other two parts, please go back and read part 1, then read part 2. Done? Ok, lets continue.

Again here the links for two examples: the Sample Database Application which will be used as example in this post and the click-click Website (which is multilingual, just change /en/ to /de/ in the URL).

This Blogpost will cover the necessary changes in an APEX Application, to work with human readable URLs.

Public Pages

Really important is that all pages in your application are set to “Public”

and that the active Authentication Scheme isn’t No Authentication (using DAD), since that would lead to problems in combination with the APEX Listener with APEX 4.2.3 and below (Bug 17796199 fixed in 4.2.4).

Cookie

In the Authorization Scheme go to the cookie section and set a cookie path, matching your base URL. On apex.oracle.com this is /pls/apex/, on the click-click Website it is /web/.

The Path is important, otherwise a new cookie (and new APEX session) would be created when visiting /home at first and /customers after that.

The Cookie Name is optional, you can also leave that blank.

Target is URL

Above we prepared the application to support our new URL structure. Now its time to walk through our application and change every Button, List Item, Branch and whatever Link you may have to use the new and shiny URLs.

A good idea here is to define an application substitution string which holds the base URL. In my demo I have defined a substitution string called G_URL which is set to /pls/apex/hrurl. In URL Targets I then can use it like this: &G_URL./customer/#CUSTOMER_ID#

Base URL to support Form Submits

So far everything works fine, we can call and show all our Pages. But when trying to submit (save) a form we get an error saying that wwv_flow.accept doesn’t exist.

This happens, because wwv_flow.accept is simply appended to the end of the active URL. e.g. http://apex.oracle.com/pls/apex/hrurl/customer/2/wwv_flow.accept

The easy workaround is to define a Base URL using a simple HTML Meta Definition.

Can you see it? It is this simple command: <base href=”/pls/apex/” />

UPDATE: older IE versions (yes, some people still call it a browser) need a fully referenced base href, like: <base href=”http://apex.oracle.com/pls/apex/” />

Now wwv_flow.accept is appended to the base URL and all submits work fine again.

Would be great, if the APEX Dev Team could include the base-URL definition automatically.

AJAX Calls and Interactive Reports

There is still a tiny problem with our friendly URLs. AJAX calls (also Interactive Reports and regular report pagination) don’t work anymore. The AJAX calls are returned with a HTML error code.

To find the reason for that I had to do a code-review of the APEX Javascript AJAX functions and found a Bug in htmldb_Get, which is the underlying function of many AJAX calls in APEX.

Problem here is htmldb_Get doesn’t use the base-URL, it tries to find f?p in the current URL and replaces that with wwv_flow.show (the AJAX Entrypoint). Our URLs don’t show f?p, so wwv_flow.show is appended to the end of the current URL, which is obviously wrong.

This Bug still exists in APEX 4.2.4, I hope it will get fixed in APEX 5.0.

There is no easy workaround here. The only option we have is to overload and redefine htmldb_Get, which I did for the demos.

Since this code is very version dependent and over 200 lines of code, I decided not to share it in this blog. If you know your way around javascript you’ll be able to get it from the demo. Otherwise you should keep your hands off.

Again: overwriting htmldb_Get is a workaround which is likely to break with the next APEX Version.

Summary

Using friendly URLs is possible today, even in older APEX Versions when using mod_plsql. There are some things you need to take care of in your application, as listed above.

Once you know your way around, it takes a couple hours to turn an existing public application into using human readable URLs.

Enjoy!



  1. Rob van Wijk on December 19, 2013

    Thanks for sharing this info in such comprehensive posts. I’ve used Apache rewrite rules, but this looks way better.

  2. Mathieu Meeuwissen on December 20, 2013

    As you stated: it only works for public applications and that is a big limitation, I think.
    Most applications will have some authentication and authorisation.

    How would you solve this matter?
    Is this something the APEX team should try to find a solutions for?

    I hope you can persuade the APEX team to have a look at it, because it is something a lot of developers would like to use.

  3. Peter Raganitsch on December 20, 2013

    I also stated, that it most likely isn’t important to have nice URLs for internal applications.

    Saying that, I can live with this workaround for the time being, but would prefer an integrated solution delivered by APEX itself.

  4. Mathieu Meeuwissen on December 20, 2013

    The real good thing about the nice URLs is that it doesn’t include the application ID.
    Users can bookmark the URL of their internal application(s).
    This means you always have to keep the same application ID.
    When the application is installed under a new application ID, all users have to change their bookmarks.

    It could be avoided by making a portal.
    But still linking between two applications also means that the calling application has to be changed when the called application gets a new application ID.

    The elegance of your solution is that the used application ID’s got be stored in a table.
    That means you only have to maintain it on one place. Much more robust.

  5. Faraz Saleem on April 7, 2014

    Hi Peter,

    I m using your given method to get a nicer url, i have implemented the steps you mentioned above.

    1. Setting all application pages authentication to public.
    2. Setting Cookie Path attributes to /pls/apex/ as mentioned above.
    3. Further i have replaced all targets to URL according to my page name along with cookie path.

    I m getting the following error while navigating to the page.

    Http Status 404- Not Found.
    type Status report
    messageNot Found
    descriptionThe requested resource is not available.
    GlassFish Server Open Source Edition 4.0

    Please help to solve the problem.

    Regards
    Faraz Saleem