Page tree
Skip to end of metadata
Go to start of metadata

Official Documentation Available

This topic is now covered in Blossom module.

Controllers used for rendering content are not accessible for requests coming in to the servlet container. Requests that come in are handled my Magnolia and mapped to content that is only later rendered by these controllers. The BlossomDispatcherServlet that manages these controllers are started in your module class and the servlet container has no knowledge of this servlet. Since these controllers are non meaningful without content there's no reason to have them directly accessible.

Controllers that should be accessible directly and are not used to render content need to be managed by a different DispatcherServlet.

There's two ways to add a DispatcherServlet in a Magnolia project. You either simply add one to web.xml or you add to your module descriptor.

Adding it to the module descriptor is the better choice because then its started after your module has started and it will become a child of the root web application context and can access all beans within it. You also won't need to update web.xml which makes module install easier and upgrades of Magnolia easier.

The module descriptor is your /src/main/resources/META-INF/magnolia/<module name>.xml file.

Here's an example of what that looks like:

<servlets>
  <servlet>
    <name>dispatcher</name>
    <class>org.springframework.web.servlet.DispatcherServlet</class>
    <mappings>
      <mapping>/ajax/*</mapping>
    </mappings>
    <params>
      <param>
        <name>contextConfigLocation</name>
        <value>classpath:/ajax-servlet.xml</value>
      </param>
    </params>
  </servlet>
</servlets>

Magnolia installs the servlet when the module is installed so after you've added it you need to reinstall your module. When it's installed you can see it in the configuration app at /server/filters/servlets/dispatcher.

In the example above the DispatcherServlet will get all requests with a path starting with /ajax/ and it uses a configuration file /src/main/resources/ajax-servlet.xml.

You'll want to make sure that ajax-servlet.xml has only the controllers that should be accessible from the outside and not those used for rendering content. Do this by organizing them in different packages and use component scan to find the right ones.

Here's what a simple ajax-servlet.xml would look like:

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:context="http://www.springframework.org/schema/context"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd">

  <context:annotation-config/>

  <context:component-scan base-package="my.module.ajax" />

</beans>

It will component scan and find the controller below which becomes accessible at /ajax/hello, note that the /ajax part is not specified in the controller.

package my.module.ajax;

import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;

@Controller
public class AjaxController {

    @ResponseBody
    @RequestMapping("/hello")
    public String render() {
        return "Hello!";
    }
}