Introduction
When a request arrives, it is routed to a controller. There must always be at least
one controller in a Mojave application. A controller is simply a POJO annotated at
the class level with one of several controller annotations. You specificy the package
location of your controllers, and during startup, Mojave will scan the package for
classes with the aforementioned controller annotations.
A controller must have at least one action, which is the method that is ultimately
called to handle the incoming request. We won't go into more detail about actions
here. To learn more about actions, please see the
actions documentation page.
Controller Types
There are three types of controllers in the Mojave framework:
- Stateless
- Stateful
- Singleton
Stateless Controller
A new instance of this controller is created per request. Its dependencies are
injected after creation.
The following are valid declarations of stateless controllers:
@StatelessController
public class SomeController {
...
}
@StatelessController("some-name")
public class SomeController {
...
}
It is important to note that as a new instance of a stateless controller is created with every
request, the developer should not design the stateless controller with state. That is, class
fields should not be used with the intention of storing state between requests, but they can be
used for storing state in the object during a request. For storing state between requests,
use a StatefulController.
Stateful Controller
Only one instance of this controller will exist per request session. It is kept in the HttpSession.
The instance goes away when the session is invalidated, the session times out, or the application
is restarted. Its dependencies, if any, are re-injected with every new request.
The following are valid declarations of stateful controllers:
@StatefulController
public class SomeController {
...
}
@StatefulController("some-name")
public class SomeController {
...
}
Singleton Controller
Only one instance of this controller will exist in the application, placed in the front controller
context. Its dependencies, if any, are re-injected with every new request.
The following are valid declarations of singleton controllers:
@SingletonController
public class SomeController {
...
}
@SingletonController("some-name")
public class SomeController {
...
}
Note that it is up to the developer to address thread-safety in singleton controllers. The single
instance will be accessed simultaneously by multiple threads, and thus there will be concurrency
issues to address. The container will not attempt to address those issues.
Singleton controllers can also be optionally annotated with the Init annotation. The singleton
controller instance will be created at startup if it is annotated with this annotation. As an example,
consider the following controller:
@Init
@SingletonController
public class StartupController {
...
}
The controller above will be instantiated during initialization of the FrontController servlet.
Default Controllers
A Stateless or Stateful controller in the Mojave framework can be annotated as the Default controller,
using the DefaultController annotation. A controller annotated with this annotation is flagged as the
default controller for all application requests not specifying a controller. Only one controller in
the application can be annotated with this annotation. As an example, consider the following controller:
@DefaultController
@StatelessController("test")
public class SomeController {
@Action
public JSP someAction() {
return new JSP("index");
}
}
We can invoke the someAction method by making the following request (provided there is no controller
named 'someAction'):
http://.../someAction
Since there was no controller name supplied, the default controller was used as the controller
for the request. However, we can also invoke the someAction method by making the following standard
request:
http://.../test/someAction
Controller Constructors
Every instance of a Mojave controller is created through the Guice injector. Therefore, if the controller
has a constructor that requires parameters, then the contructor must be annotated with the Inject
annotation, and the application's Guice modules must be configured appropriately. The Mojave framework
supports injecting the HttpServletRequest, HttpServletResponse, and HttpSession out-of-the-box. (Injection
of the ServletContext, however, is not currently allowed.) There is no module configuration required to
support injecting instances of these types. Also, controllers can be injected into other controllers.
@StatelessController
public class SomeController {
private final HttpServletRequest req;
private final HttpServletResponse resp;
private final HttpSession sess;
@Inject
public SomeController(HttpServletRequest req, HttpServletResponse resp, HttpSession sess) {
this.req = req;
this.resp = resp;
this.sess = sess;
}
...
}
|