You have two options for creating controller classes. You can extend the classes provided by SpringMVC or you can extend classes provided by Teradata Viewpoint. Both types of classes are configured the same way in your application configuration files.
Documentation for the SpringMVC controller classes can be found at the Spring Framework web site and in several books.
Teradata Corporation recommends using the Teradata Viewpoint controller classes. These classes have been optimized for writing Teradata Viewpoint portlets, so you will write much less code and that code will be simpler and easier to maintain and test. The biggest advantage of the Teradata Viewpoint controller classes is code reuse. You can use the same code to respond to both portlet and servlet requests. Also, you can use the same code to handle user preferences forms and portlet configuration forms (assuming the forms have the same content, which they usually do).
This page documents how to implement Teradata Viewpoint controller classes. For information on how to integrate these controller classes into your application, see How to Create a View Controller and How to Create a Preferences Controller.
There are two Teradata Viewpoint controller classes:
Both of these classes have a common set of methods that you will use to implement your controller functionality. These common methods can be found in the javadocs for the ControllerContext class.
In every request handling method in a Teradata Viewpoint controller, you have access to a ControllerContext parameter. This parameter provides access to all of the information you need about the request and response. The following sections describe the methods available via this parameter (the parameter is abbreviated ctx in the following examples).
The following examples illustrate the basic, built-in capabilities of the Teradata Viewpoint controller and FormController based controllers that you are likely to use in every portlet that you write.
You can access the parameters specified in the incoming request using getParameter:
String context = ctx.getParameter("context");
You can specify which view to use to render the response using setViewName:
ctx.setViewName("summary");
Spring will use the viewResolver rules to find the associated view implementation. This command would normally execute WEB-INF/portlet-jsp/summary.jsp.
You can pass java objects to your view using addViewObject:
ctx.addViewObject("pigsCanFly", false);
In your JSP file, you can use JSP expression language to reference a view object by its name:
<c:if test="${pigsCanFly}">
<img src="/images/flyingPig.jpg" />
</c:if>
Your controller can read and write attributes. Attributes are java objects that can be stored at one of four levels:
Here is an example:
Integer currentDepth = (Integer) ctx.getAttribute("depth", AttributeLevel.SESSION);
ctx.setAttribute("nextDepth", currentDepth + 1, AttributeLevel.REQUEST);
Because portlet preferences are referenced so frequently in controllers, there is a built-in interface to load and save them. For example:
// get the user's preferences for this portlet instance
SkewedSessionsPreferences preferences = new SkewedSessionsPreferences();
preferences = ctx.loadPreferences("skewedSessions", preferences);
The Portal Role Manager allows the administrator to configure portlet defaults for all users. Your portlet needs to provide the implementation of the configuration form. The loadPreferences and savePreferences methods are smart enough to know if they are being called from your configuration form or your user preferences form and automatically perform the correct action to load or save portlet default preferences or user preferences.
This means that you can usually re-use the same view and the same controller for both configuration and preferences.
The following examples illustrate the additional built-in capabilities of ViewpointController and ViewpointFormController classes that you may need for more complex portlets.
If you need to know the URL that initiated the request that you are processing, you can get it with the getRequestURL method:
String url = ctx.getRequestURL();
If you need to know the portal username (the name under which the user logs in to the Teradata Viewpoint portal), you can use getRemoteUser:
String username = ctx.getRemoteUser();
NOTE: This method only works in portlet requests, not in servlet requests.
If you need to know the value of cookies that have been set in the browser, you can use getCookies to read them:
import javax.servlet.http.Cookie;
...
Cookie[] cookies = ctx.getCookies();
If you want to set a cookie value, you can use setCookie:
Cookie tabCookie = new Cookie("defaultTab", "2");
ctx.addCookie(tabCookie);
NOTE: This method only works in servlet requests, not in portlet requests.
Implementing a multi-page portlet (such as a portlet that supports drill-down from a summary page to a detail page) requires implementing multiple controller methods (typically one for each page). Let's start with a simple example: a portlet does not auto-refresh and has two pages. The first page displays data in a table and the second page displays data in a graph. We have a link in each page that points to the other page.
Teradata Viewpoint controllers automatically recognize a parameter named pageName and try to find a controller method with the same name. Also, you need to know that the default page name is summary. If there is not pageName parameter (as when the portlet is initially displayed on the page), then the summary method is invoked. So you would create your controller like this:
class TwoPageExampleController extends ViewpointControllerBase
// this is called when there is no pageName parameter
public void summary(ControllerContext ctx)
{
table(ctx);
}
// this is called when pageName = "table"
public void table(ControllerContext ctx)
{
ctx.setViewName("table");
// create view objects for table view
...
}
// this is called when pageName = "graph"
public void graph(ControllerContext ctx)
{
ctx.setViewName("graph");
// create view objects for graph view
...
}
}
Then, in the portlets-jsp directory, create the JSP files for the two views. Here is table.jsp:
...
<vp:TableWidget .../>
<portlet:renderURL var="graphURL">
<portlet:param name="pageName" value="graph"></portlet:param>
</portlet:renderURL>
<a href="${graphURL}">View as graph</a>
...
Here is graph.jsp:
...
<vp:GraphWidget .../>
<portlet:renderURL var="tableURL">
<portlet:param name="pageName" value="table"></portlet:param>
</portlet:renderURL>
<a href="${tableURL}">View as table</a>
...
The user has the option of maximizing your portlet so that it is the full width of the portal. You may want to take advantage of this to display additional data. For example, if you are displaying a graph, you might want to display twice as many data points. Or, if you are displaying a table, you might want to display additional columns. You can detect whether or not the portlet is maximized using the getWindowState method. Here is an example:
if (ctx.getWindowState().equals(WindowState.MAXIMIZED))
{
columns = Arrays.asList(preferences.getMaximizedSummaryColumns());
}
else
{
columns = Arrays.asList(preferences.getSummaryColumns());
}
Normally a response to a request returns HTML content. If you want to return a different type of content, you need to specify the mime-type of the content. The setContentType method allows you to do this. For example, if you want to return javascript, you add this method call to your controller:
ctx.setContentType("text/javascript")