You are viewing an old version of this page. View the current version.

Compare with Current View Page History

Version 1 Next »

Introduction

There are more and more multi-site users of Magnolia CMS asking us for a customizable, multi-language enabled, site aware and out of the box solution from Magnolia CMS to support web container servlet exception handling. As a multi-site user of Magnolia CMS, you can have multiple sites configured and mapped by multiple URLs / Domains / Hosts. Whenever an issue happen such as Resource not found (HTTP 404 status code) or server error (500 internal server error), web container will redirect us to its default error report page. If we don't have corresponding configuration, we cannot have a nice error report to our valued customers.

A typical example is when end user calling this link https://demopublic.magnolia-cms.com/travel/ where is my tour?

This is what we get from a non-configured site

This guideline provide you with how to have it and how it has been made so that you can easily use it and customize it based on your practical situation.

Installing

First of all in order to make our web-container such as Apache Tomcat aware of our customization, we would have to put snipped of code this to our ''Tomcat/webapps/YOUR-MAGNOLIA-WEBAPP/WEB-INF/web.xml' file just above the closing of 'we-app' tag (above this "</web-app>").

<error-page>
  <exception-type>java.lang.Exception</exception-type>
  <location>/.exception</location>
</error-page>

Please note that we are using a specific location "/.exception" for all every "java.lang.Exception' ones, you could also change it in case of conflict with any of your existing one. Later on we will show where the mapping is. So if you change it here, you would also have to change the other one for direct mapping of exception handling page.

Put the pre-built module to your 'Tomcat/webapps/YOUR-MAGNOLIA-WEBAPP/WEB-INF/lib' folder then restart your server and install the new module.

Using and Configuring

After successfully installed the module, when accessing a nonexistence page such as http://localhost:8080/travel/ abc, you will have this:

All the configuration points should located under our pre-built module such as 'mgnlsupport' module below:

Basically we provided a default exception page template, its configuration is under our module 'templates/pages/exception' node as any other template configuration. You can reference to our official documentation for template configuration guidelines.

Also we provided 2 site-aware exception mappings which have been configured out of the box pointing to 2 default exception pages for our 'travel' demo site and the 'fallback' one.

You should be able to locate our 2 default exception pages under our pages app as below image:

Customizing and Developing

Changing exception page location

As you can easily find that we have this configuration point '/modules/mgnlsupport/virtualUriMappings/travel-exception-mapping@toUri' which has the value as 'forward:/travel/exception' then if you have another page somewhere for your site, you can easily change the page location from '/travel/exception' to your new one. The working mechanism is described in our official Virtual URI mapping function. 

Changing exception page template

We already provided you with a sample (not very fancy) page template within our pre-built package under '/mgnlsupport/src/main/resources/mgnlsupport/templates/pages/exception.ftl' (in this case my module name is mgnlsupport, will change it later when I have time). Then we have a configuration point for it such as 

'/modules/mgnlsupport/templates/pages/exception@templateScript=/mgnlsupport/templates/pages/exception.ftl'

Then just follow our light-dev guideline, provide your own template and point to to appropriate classpath folder then the new FTL file will be used for our configured template.

Implementing another kind of mapping or exception handling

Basically I just created a custom module with below structure and provided you with a site aware URI mapping as below:

Sample code:

SiteAwareExceptionMapping
package info.magnolia.virtualuri.mapping;

import java.net.URI;
import java.util.Optional;

import javax.inject.Inject;
import javax.servlet.http.HttpServletRequest;

import org.apache.commons.lang3.StringUtils;

import info.magnolia.cms.util.UrlPattern;
import info.magnolia.context.MgnlContext;
import info.magnolia.module.site.Site;
import info.magnolia.multisite.sites.MultiSiteManager;

public class SiteAwareExceptionMapping extends DefaultVirtualUriMapping {
    
    public static final String SERVLET_ERROR_REQUEST_URI_ATTRIBUTE_NAME = "javax.servlet.error.request_uri";
    
    private String siteName;

    @Inject MultiSiteManager msm;

    @Override
    public Optional<Result> mapUri(URI uri) {
        UrlPattern pattern = getPattern();
        if (pattern != null && pattern.match(uri.getPath())) {
            String ctxPath = MgnlContext.getContextPath();
            HttpServletRequest req = MgnlContext.getWebContext().getRequest();
            String exceptionUri = req.getAttribute(SERVLET_ERROR_REQUEST_URI_ATTRIBUTE_NAME).toString();
            String resourceUri = exceptionUri.substring(ctxPath.length());
            Site site = msm.getAssignedSite(req.getServerName(), resourceUri);
            if (StringUtils.equalsIgnoreCase(siteName, site.getName())) {
                return super.mapUri(uri);
            }
        } 
        return Optional.empty();
    }

    public String getSiteName() {
        return siteName;
    }

    public void setSiteName(String siteName) {
        this.siteName = siteName;
    }
    
    
}


This source code is provided without any guarantee as a community creative & publicly available one. Please use it with cares and a bit or risks.

References

This is an upgraded version of How to setup a custom 404 handler as of January 2018 because the previous one has been out dated and did not maintained for such a long time. We're trying to bring values to customers who are using and contributing to Magnolia CMS.


  • No labels