Skip to content

Toro Cloud Dev Center


Serving web content

Martini has an embedded instance of Tomcat included to enable it to service HTTP requests, which includes SOAP and RESTful APIs. Martini also leverages Tomcat to enable a Martini package to serve its own webapps.

If your Martini package has a web directory, it will be scanned and added to Tomcat during package start-up as a web application.

The web directory does not exist by default

Creating a package does not automatically create the package's respective web directory. To create a new directory inside your package, right click your package from the Navigator, and then select New > Folder. Your package must be loaded to allow this action.

Creating a new package sub-directory

Creating a new package sub-directory

Furthermore, the presence of a web.xml file in the web/WEB-INF directory tells Martini and Tomcat that your webapp's configuration is customized, and this configuration will be used as opposed to the default webapp configuration Martini creates for packages without web.xml files.

Effectively, this means you can deploy your web applications to Martini and use all the APIs available to build your website faster. You can invoke services and have them render JSP pages and serve web pages the MVC way using either Gloop or Groovy APIs!

The package lifecycle and Tomcat

If a package is stopped, then its associated web context will be stopped and removed from Tomcat as well.

Martini support for HTML, JSP, CSS, and JS

You can create and edit your HTML, JSP, CSS, and JS files in Martini.

Build and serve web pages the Gloop way!

Instead of JSP, you can also generate and conveniently serve web content through Gloop templates. Gloop templates inherit the power of services, making it super easy to create dynamic web pages for your application, especially those already running in Gloop.

Creating a default package homepage

It's easy to create a default homepage for your packages. All you have to do is place a JSP web page in your package's web directory and ensure it is named index.jsp. A restart is not required. You may view your package's homepage at <host>:<port>/<name-of-package>, where <host>:<port> is the root address of your Martini server.

`examples` package homepage

Serving web content

Martini runs on top of Spring, and re-exposes many of the framework's capabilities – including the ability to serve web content through Spring MVC.

MVC pattern

The model-view-controller (MVC) pattern is a popular architectural pattern typically used in web applications. Under this pattern, an application is split into three logical components, each built to handle a specific function.

In this section, we'll go through the process of (1) creating a view, (2) creating a web controller, and (3) using a controller-provided model in the view.

Creating a view

ViewResolvers in Spring are used to find views by name. Martini's configured ViewResolver in particular, looks for .jsp-suffixed views under the package web directory.

Consider hello.jsp below, placed right under a package's web directory:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
<!DOCTYPE HTML>
<html>
<head>
    <meta charset="utf-8">
    <title>Greetings from Martini</title>
</head>
<body>
    <p>Hello, ${name}!</p>
</body>
</html>

This view will display Hello, ${name} in the browser. ${name} is a variable, and will be replaced accordingly when rendered with a web controller-provided value.

Creating a web controller

In Gloop, web controllers are made through ad hoc services or Gloop REST APIs. At a minimum, the mapped service should return an output property named $gloopView whose value is set to the name of the view you want to use.

For example:

`GreetingController`

`GreetingController`

This controller maps HTTP requests to api/hello/{name}1 to GreetingController.gloop. It receives and returns a property called name (via path parameter) to the view, and sets the view hello for said mapping.

service output properies as model attributes

The mapped service's output is used as the model, and can be accessed via JSTL in the named JSP.

To recreate this controller in your own instance, follow these steps:

  1. Create a service.
  2. Declare an input property called name.
  3. Declare an output property called name.
  4. Declare an output property called $gloopView.
  5. Add a map step, and map the name input property to the name output property.
  6. Add another map step, and set $gloopView's value to hello.
  7. Configure the service's REST properties so that it is exposed at your desired path. In this case, expose your service as a GET operation at /hello/{name}.

In Groovy, the simplest way to define a controller is through the use of Spring annotations. For example:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
import org.springframework.stereotype.Controller
import org.springframework.ui.Model
import org.springframework.web.bind.annotation.GetMapping
import org.springframework.web.bind.annotation.PathVariable

@Controller
class GreetingController {

   @GetMapping('hello/{name}')
   String sayHello(@PathParam String name, Model model) {
        model.addAttribute('name', name)
       'hello'
   }

}

This controller maps HTTP requests to /hello/{name} to the sayHello() method. It adds a name attribute, whose value is derived from the path parameter name, to the model which will be passed to the view. And lastly, it configures a view named hello for said mapping.

That's all it takes to create a web controller? What am I missing?

While simple, there's a lot going on behind the scenes for the controller to work - a lot of stuff you won't have to worry about because they are taken care of by Spring.

Check your model, controller, and view in action

Upon saving, Martini will compile your code and register your mappings. Once this is done, you'll be able to access your view in browser using said mappings.

Gloop MVC in action

Gloop MVC in action

Groovy MVC in action

Groovy MVC in action


  1. The leading path /api is defined through the api.rest.base-path application property. This path may be different depending on your instance's configuration.