Download pulse

Hello pulse - Hello world

What else could it be, but the classic HelloWorld? In this section we will create a simple Controller (i.e. the classes which provide web methods - methods which can be initiated by HTTP requests - in pulse). And while we're at it, you will discover how web method access, permissions and groups are simply controlled via annotations.

The code

The following is a very simple Controller. All it does is to print "Hello World" to the log file.

package org.torweg.pulse.component.example;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.torweg.pulse.annotations.Action;
import org.torweg.pulse.bundle.Controller;

public class HelloWorldController extends Controller {

	private static final Logger LOGGER = LoggerFactory

	public final void helloWorld() {"Hello World");


Place the above file into examples-for-pulse/components/example/src/java into the appropriate package. Then all we need to do is to expose the Controller. This is done by adding it to a bundle.xml.

We will expose the HelloWorldController in the Example bundle. So please edit examples-for-pulse/bundles/Example/bundle.xml to include the Controller:

<?xml version="1.0" encoding="UTF-8"?>
    <!-- controllers exposed by this Bundle -->
        <controller class="org.torweg.pulse.component.example.HelloWorldController"/>

    <!-- the implementations of exposed by this Bundle -->

    <!-- the Joblets of this Bundle -->

Then build and deploy the webapp using ant.

Say hello...

Start your server, open a browser and go to the starting page of your pulse installation. Make sure you not logged in.

Now enter the following URL in your browser (please adapt host name, port and webapp name when necessary):


You should receive a "403 Forbidden" response in the default pulse layout. That's fine, because non-authenticated users are not supposed to use the controller.

Now, log in as root and look into log-file. It should read something like:

2010-09-24 20:04:38 INFO  [0:0:0:0:0:0:0:1] org.torweg.pulse.component.example.
HelloWorldController - Hello World

If you are using the demo layout the screen in your browser should be similar to this:

Well, hello then...

How does it work?

The HelloWorldController contains the method "helloWorld" which does the actual work of logging the text. By using the @Action annotation, we declare that this is a method which should be callable via HTTP. By adding the Controller to a bundle.xml we finally expose it to the outside world.

In pulse every @Action annotated web method, is available by a unique Command. How these commands relate to the web method's of a controller and how to read a the URI representation of a pulse command is described in the class documentation of Command.

If you took a look into the documentation, you will have noticed that the command http://localhost/pulse/Pulsar/.Example.helloPulse../ can be decoded as:

  • locale: undefined
  • bundle: Example
  • action: helloPulse
  • sitemapNodeID: undefined
  • pulseParameters: omitted

When a command points to a specific bundle, all Controllers with matching @Action annotations are processed. If the user is allowed to execute the action (more on security below), the corresponding methods are executed. It's as simple as that.

Managing security

By design pulse prohibits access to all actions, but there is one exception: the superuser root, who is allowed to execute any action.
You should read how access rights are managed within the administration before continuing the tutorial.

To allow ordinary users access to a web method, you will need to assign a permission to the method. This is done with the @Permission annotation.

public class HelloWorldController extends Controller {

    private static final Logger LOGGER = LoggerFactory

    @Groups(values = { "example" })
    public final void helloWorld() {"Hello World");


Amending the code like shown above and restarting the webapp will cause two things to happen:

which will be instantly available in the user administration interface.

Naming systematics

All auto-generated Roles, Groups and Permissions will always start with a ~. This makes them easy to identify.

The name of a generated permission is always according to the following scheme:

~{name of bundle}:{simple class name of controller}:{name of permission}

The names of Groups are build in a similar way:

~{name of bundle}:{name of group}

Web methods to be run on every access

So you've already learned about the three most important annotations for web methods: @Action, @Permission and @Groups. However there is a fourth annotation - @AnyAction - which defines web methods that shall be executed on every request to pulse.

public class HelloWorldController extends Controller {

    private static final Logger LOGGER = LoggerFactory

    @Groups(values = { "example" })
    public final void helloWorld() {"Hello World");

    public final void alwaysRun() {"I run always"); 
<controller class="org.torweg.pulse.component.example.HelloWorldController" alwaysRun="post"/>

There are some subtleties attached to the execution of @AnyAction annotated methods which are explained in the configuration section.

Further reading

Whenever there are good examples for the current section to be found in the pulse distribution, we will recommend these classes for further reading. Moreover we encourage you to take a look to your left and right and explore the packages you visit.
It's a good way to learn, if you study the way we make use of our own framework.


Maybe you've already noticed this: our JavaDoc is linked with souce code. Whenever you follow a link to the code documentation (e.g. Controller) you can click on the constructor or method name in the details description to get directly to the corresponding, syntax highlighted source code from the latest stable release.