Blogs

Spring MVC Support in dotCMS 2.0

dotCMS 2.0 will ship with support of Spring 3.1 MVC as a web development framework. In version 2.0, dotCMS includes a Spring View and Spring ViewResolver that allows a developer to use the standard Spring Web MVC framework with dotCMS templates/pages acting as the view. With this, web developers to easily create or port Spring MVC driven app to a content managed platform, where dotCMS (and your marketing team) can manage the templates and content and Spring can manage the business logic and applications.

How to get started with Spring + dotCMS:

1) Creating the Controller

The easiest way to get started is to create a Spring MVC Controller. Spring Controllers are very simple and only need to annotate themselves a "@Controller". One nice thing is that a Controller's actions can be mapped completely via annotations - with their application namespace starting with /spring/. This means, if you annotate your Controller with:

@RequestMapping("/helloworld")

It will be automatically invoked when the url /spring/helloworld is requested.

This allows you to map different methods to different URIs, e.g.:

@RequestMapping(value = "/", method = RequestMethod.GET)
public ModelAndView helloWorld() {}
@RequestMapping(value = "/hello/{userName}", method = RequestMethod.GET)
public String getHello(@PathVariable String userName, Model model) {}

If you'd like to map a different namespace (rather than /spring/) to Spring MVC, you can do so by adjusting the Spring DispatcherServlet mappings in /WEB-INF/web.xml

In dotCMS, Spring is set to autoscan for valid Controllers, looking for any @Controller under the package com.dotcms.spring.web.* If you'd like to change this behavior, you can do so in the file: /WEB-INF/springmvc-servlet.xml.

Here is the entire code for the HelloWorld Controller Class:

package com.dotcms.spring.web;

import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.servlet.ModelAndView;

import com.dotmarketing.util.Logger;

@Controller
@RequestMapping("/helloworld")
public class HelloWorldController {

  @RequestMapping(value = "/", method = RequestMethod.GET)
  public ModelAndView helloWorld() {
    String myMessage = "Hello World, Spring 3.1 and dotCMS!";
    // This will resolve to /application/spring/helloworld.dot, and 
// put the String myMessage in the map with key "message" return new ModelAndView("helloworld", "message", myMessage); } @RequestMapping(value = "/{userName}", method = RequestMethod.GET) public String getHello(@PathVariable String userName, Model model) { Logger.debug(this.getClass(), "Received request to hello user"); // set the message String aMessage = (userName != null) ? "Hello " + userName + ", welcome to Spring 3.1 and dotCMS! " : "Hello Total Stranger, welcome to Spring 3.1 and dotCMS! "; // Attach message to the Model model.addAttribute("message", aMessage); // This will resolve to /application/spring/helloworld.dot return "helloworld"; } }


You can see from in the above class that we have two methods. The first maps to the controllers root namespace, /helloworld and adds a message to the velocity context for every GET request.  The second method is more interesting.  It uses the URI as a parameter:

@RequestMapping(value = "/{userName}"

and allows the invoked method  to use that parameter.  This allows you (the developer) to use that parameter to perform a lookup or somesuch as needed by your code.  With Spring, parameters can be mapped using regexs and other more complex patterns, all of which are supported. How to develop a full web app with Spring MVC is outside the scope of this blog post, but as you can see, the addition of Spring MVC tooling opens up a world of development possibilities. 

2) Creating the View

By default, dotCMS looks for the view (the .dot page) under /application/spring/${ControllerMapping}.dot. So if you have mapped a Controller to:

/signup

dotCMS will try to resolve the view as

/application/spring/signup.dot

This behavior can be adjusted in the /WEB-INF/springmvc-servlet.xml and you can set the prefix and suffix that will be prepended and appended to your mapping.

In your view page, you will have full access to any objects added to the Model in your controller.  dotCMS automatically adds the Model to your velocity context before any rendering is done.  This means if you set a List of products in your Model in the controller with the key of "products", it can be accessed anywhere in your Velocity based dotCMS templates/containers/content/widgets as $products. Generally, you create a "Simple Widget" that can be placed in any template/container to display the resultant Spring view. In the above example, you would create a Simple Widget that would loop over the products in the list provided by the Controller. The Widget Code would look something like:

${esc.h}foreach(${esc.d}product in ${esc.d}products)
${esc.d}product.title
${esc.h}end

3) That's it!

No really.  Our example is missing the M in the MVC - the domain model -   but this changes regarding your specific business needs.   A Spring Controller can literally be created and deployed as a dotCMS plugin made up of a single java class.  Getting productive using Spring MVC in dotCMS is very easy - with no extra wiring required.

March 07, 2012

Filed Under:

dotcms 2.0 spring mvc

Recommended Reading

Headless CMS vs Hybrid CMS: How dotCMS Goes Beyond Headless

What’s the difference between a headless CMS and a hybrid CMS, and which one is best suited for an enterprise?

Why Global Brands Need a Multi-tenant CMS

Maintaining or achieving a global presence requires effective use of resources, time and money. Single-tenant CMS solutions were once the go-to choices for enterprises to reach out to different market...

14 Benefits of Cloud Computing and Terminology Glossary to Get You Started

What is cloud computing, and what benefits does the cloud bring to brands who are entering into the IoT era?