The Mojave framework requires that all controller actions return
a View . A View is simply an interface
with a single method: render .
public interface View {
void render(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException;
}
The render method is invoked last in the sequence of steps
involved in processing a request sent to the FrontController. The provided servlet
request can be used to set attributes, then to obtain a RequestDispatcher
for forwarding or including; or, the servlet response may be used to send a
redirect, for example.
It should be noted that any exceptions thrown from the render
method are not guaranteed to be caught in the FrontController. They may escape to
the requestor. Developers should handle any exceptions inside the implementation
of the render method if different behaviour is desired.
The Mojave framework does not try to impose too many restrictions
on what a View does in any given application, so developers
are encouraged to implement their own. Nevertheless, the Mojave framework
does provide some View implementations out-of-the-box that
correspond to common use cases.
JSP Views
The Mojave framework provides a View implementation called
JSP . This class is meant for applications that use Java Server
Pages, or JSPs, to render their views. To use this class, the
jsp-path init param must have been specified at start-up. When the
render method in invoked, the RequestDispatcher is
obtained for the specified JSP page, and the request is forwarded to it. Finally,
it is also useful to note that the class provides methods for setting attributes
using a fluent interface.
@StatelessController
public class HelloWorld {
@Action
@ParamPath("to/:name")
public View sayHello(@Param("name") String name) {
return new JSP("hello").withAttribute("name", name);
}
}
Redirects
Often, it is necessary to redirect a request. To do this in the Mojave framework,
a View implementation called Redirect is provided. The
constructor for the class takes a single String argument, which is the redirect
location. Invoking the render method simply invokes
HttpServletResponse.sendRedirect(location) .
@StatelessController
public class HelloWorld {
@Action
public PlainText sayHello() {
return new PlainText("Hello World!");
}
@Action
public View redirectToSayHello() {
return new Redirect("sayHello");
}
}
Streams
An HTTP request is not limited to receiving HTML content in reply. There are many different
content types supported. The body of an HTTP response can carry any form of data in the
form of raw bytes--no content encoding is required, so long as the client making the
request can understand the response. The Servlet specification makes available the response
OutputStream, so that binary data can be written to the body of the response. The Mojave
framework provides an abstract class, StreamView , that works with the response
OutputStrean, and performs the necessary I/O in the implementation of the render
method. This should make it convenient for developers needing to send binary data back in the
response.
@StatelessController
public class HelloWorld {
@Action
public View getPDF() {
return new StreamView() {
@Override
protected byte[] getPayload() {
return getPDFBytes();
}
@Override
protected String getContentType() {
return "application/pdf";
}
};
}
}
As extensions of the StreamView , the Mojave framework also provides the
JSON , XML , and PlainText View
implementations. Each of these classes contain a single constructor that requires a
String representing the fully formed content. The Mojave framework does not provide
classes for interconverting between objects and XML or JSON.
@StatelessController
public class HelloWorld {
@Action
public PlainText sayHello() {
return new PlainText("Hello World!");
}
@Action
public JSON sayHelloInJSON() {
return new JSON("{\"data\":\"hello\"}");
}
@Action
public XML sayHelloInXML() {
return new XML("hello");
}
}
Customized Responses
Some use cases may require that the response contains a particular status code, with
additional information in headers, in addition to an optional content payload. For these
cases, the Mojave framework provides the Response class. The Response
class gives the user fine grained control over the response being sent to the requestor,
through a fluent interface.
@StatelessController
public class HelloWorld {
@Action
public View customizedResponse() {
return new Response.OK()
.withContent("it is ok")
.withHeader("My-Custom-Header", "123")
.withLastModified(new Date());
}
}
|