Extreme Java When vanilla Java is not enough


vHost capabilities with Wicket

I started using Wicket because I liked how easy is to create SEO URLs and design-centric applications. One crazy feature I got working was customizing an application based on the vhost. The example I asked on StackOverflow used a fictional "abc.com" hosting with "abc.com.br" and "abc.com.pl" aliases.

The example works as this: all three vhosts are on the same codebase (i.e. the same "host" on Tomcat, with three aliases) and shows the same data. The difference between ".com", ".com.br" and ".com.pl" relies on how the data is shown to the user. There are two major country-related materials:

  1. Page design - ".com" must see an American tribute (USA is #1, American Flag, etc); ".com.br" must show Brazilian stuff (Samba, Soccer teams, etc); ".com.pl" shows Polish material. This was really easy, using a ResourceStreamLocator in my Wicket Application:
        new ResourceStreamLocator() {
      public IResourceStream locate(Class clz, String path) {
        String host = ((WebRequest) RequestCycle.get().getRequest())
        String basePath = trimFolders(path);
        IResourceStream res = super.locate(clz, host + "/" + basePath);
        return (res != null) ? res : super.locate(clz, basePath);
      private String trimFolders(String path) {
        return path.substring(path.lastIndexOf("/") + 1);
  2. Contextual URL mounting - this part was hard. Assume a page named "Page1". It must be accessed using "abc.com/page1", "abc.com.br/pagina1" and "abc.com.pl/strona1", but not with combinations (e.g. "abc.com/strona1"). After asking in SO, I got an answer from "biziclop" that lead me to the solution I wanted. It's a servlet filter mapping vhost to WicketFilter instances, isolating Wicket application instances (as biziclop sugested):
    @WebFilter(urlPatterns = "/*")
    public static class Filter implements IWebApplicationFactory,
                                          javax.servlet.Filter {
      private final Map filters = new HashMap();
      private final ThreadLocal hosts = new ThreadLocal();
      private FilterConfig config;
      public void init(FilterConfig filterConfig) {
        this.config = filterConfig;
      public void destroy() {
        for (WicketFilter w : filters.values()) {
      public void doFilter(ServletRequest request,
          ServletResponse response,
          FilterChain chain) throws IOException, ServletException {
        try {
          getFilterForHost().doFilter(request, response, chain);
        } finally {
      private WicketFilter getFilterForHost() throws ServletException {
        String host = hosts.get();
        if (!filters.containsKey(host)) {
          WicketFilter w = new WicketFilter() {
            protected IWebApplicationFactory getApplicationFactory() {
              return Filter.this;
          filters.put(host, w);
        return filters.get(host);
      public WebApplication createApplication(WicketFilter wf) {
        return new WicketApp(hosts.get());

Filed under: Java EE Leave a comment
Comments (0) Trackbacks (0)

No comments yet.

Leave a comment



No trackbacks yet.