Droplets are the backbone of front-end content for all ATG applications. A droplet allows dynamic content to be easily weaved into JavaServer Pages (JSPs). Because droplets are easy to insert into JSPs, developers without Java knowledge can handle the rendering of dynamic content.
Out of the box, ATG comes with a large selection of droplets for most common tasks like iterations, repository lookups, page linking etc. When these droplets don’t fit the requirement, customizations are necessary. Fortunately, custom droplets are very easy to write. The focus of this post is to walk through the steps involved in creating a custom droplet.
The sample droplet will simply say hello to the user on the page using the user’s profile to retrieve their name if it is set. To begin, I’ll give a high level design, followed by a walk through of each important element in the droplet code for this. You can find the complete droplet code below. Add the Java file that comprises that code into the com.test.droplet package and the properties file into /test/droplet for everything to work correctly.
package com.test.droplet;
import atg.core.util.StringUtils;
import atg.servlet.DynamoHttpServletRequest;
import atg.servlet.DynamoHttpServletResponse;
import atg.servlet.DynamoServlet;
import atg.userprofiling.Profile;
import javax.servlet.ServletException;
import java.io.IOException;
import java.text.MessageFormat;
public class SayHelloDroplet extends DynamoServlet {
//input parameters
private static final String PARAM_PROFILE = “profile”;
private static final String PARAM_CURRENT_PAGE = “currentPage”;
//output parameters
private static final String PARAM_MESSAGE = “message”;
private static final String PARAM_ERROR_MESSAGE = “errorMsg”;
//open parameters
private static final String OPARAM_OUTPUT = “output”;
private static final String OPARAM_ERROR = “error”;
@Override
public void service(DynamoHttpServletRequest pRequest, DynamoHttpServletResponse pResponse) throws ServletException, IOException {
Profile profile = (Profile) pRequest.getObjectParameter(PARAM_PROFILE);
if(profile == null) {
// render error
pRequest.setParameter(PARAM_ERROR_MESSAGE, “The passed in Profile was null.”);
pRequest.serviceParameter(OPARAM_ERROR, pRequest, pResponse);
} else {
String name = (String) profile.getPropertyValue(“firstName”);
if(StringUtils.isBlank(name)) {
name = profile.getRepositoryId();
}
String currentPage = pRequest.getParameter(PARAM_CURRENT_PAGE);
// render output
if(StringUtils.isBlank(currentPage)) {
pRequest.setParameter(PARAM_MESSAGE, MessageFormat.format(“Hello, {0}.”, name));
} else {
pRequest.setParameter(PARAM_MESSAGE, MessageFormat.format(“Hello, {0}, thanks for visiting {1}.”, name, currentPage));
}
pRequest.serviceParameter(OPARAM_OUTPUT, pRequest, pResponse);
}
}
}
High Level Design
There are two sides to examine when trying to comprehend how droplets work. First, there’s the ATG API side, where we’re actually writing a class to do a custom action. That part isn’t bad, so we’ll be focusing on the JSP side of things where understanding of droplet syntax is important. Droplets are declared in the following way:
<dsp:droplet name=”/path/to/MyDroplet”>
<dsp:param name=”foo” value=”bar”/>
<dsp:oparam name=”output”>
<dsp:valueof param=”myOutputParam”/>
</dsp:oparam>
<dsp:oparam name=”error”>
<dsp:valueof param=”myErrorParam”/>
</dsp:oparam>
</dsp:droplet>
This sample droplet can be split into a few different elements:
- Declaration – Every droplet starts with a dsp:droplet tag and a name attribute corresponding to the Nucleus path of the droplet.
- Input Parameters (optional) – Specified as the first children of the droplet tag using the dsp:param tag. These are values passed into the droplet that are required for the execution of the particular droplet.
- Open Parameters – Identified using dsp:oparam tags, these can be thought of as paths the program can flow. Depending on what happens inside the droplet, one or many open parameters will be serviced.
- Output Parameters – Values set in the droplet that are passed back to the JSP. These are set in the JSP as page parameters.
Basic Steps to Writing
Droplets can be confusing at first, but they are extremely simple. There is a common process that does not change for each droplet. Here are the simplified steps to writing a droplet:
1. Create a Java class extending atg.servlet.DynamoServlet and overriding the service(DynamoHttpServletRequest pRequest, DynamoHttpServletResponse pResponse) throw ServletException, IOException method.
public class SayHelloDroplet extends DynamoServlet
2. Create a matching ATG component for the class. The scope of the component should be global.
$class=com.test.droplet.SayHelloDroplet
$scope=global
$description=Prints hello to the user
3. Declare the droplet in the JSP
<dsp:page>
<h1>Sample Droplet</h1>
<dsp:droplet name=”/test/droplet/SayHelloDroplet”>
<dsp:param name=”profile” bean=”/atg/userprofiling/Profile”/>
<dsp:param name=”currentPage” value=”SampleDroplet.jsp”/>
<dsp:oparam name=”output”>
<dsp:valueof param=”message”/>
</dsp:oparam>
<dsp:oparam name=”error”>
Error: <dsp:valueof param=”errorMsg”/>
</dsp:oparam>
</dsp:droplet>
</dsp:page>
Input Parameters
Input parameters are an optional, but usually used, part of droplets. They are the way to pass primitives or objects into the droplet. In the example, the Profile object is the only input parameter. Input parameters are passed to the droplet using the dsp:param tag from the dsp tag library using one of three variations:
- Using the value tag to add a raw (or expression language) value: <dsp:param name=”myParam” value=”my value”/>
- Using the paramtag to pass a page parameter by name: <dsp:param name=”myParam” param=”somePageParam”/>
- Using the bean tag to use the value of an ATG component as in the example
- : <dsp:param name=”profile” bean=”/atg/userprofiling/Profile”/>.
On the Java side of things, input parameters are commonly accessed using two methods. If the parameter being passed in is a String, use pRequest.getParameter(String pParamName). In the example, the currentPage parameter is passed in and resolved:
String currentPage = pRequest.getParameter(PARAM_CURRENT_PAGE);
Also note, primitive values are usually passed in this way. They are resolved using Integer.valueOf(String pValue), Boolean.valueOf(String pValue) etc.
If the input parameter passed in is an object, use pRequest.getObjectParameter(String pValue) to resolve the parameter. In the example, the user’s Profile was retrieved this way:
Profile profile = (Profile) pRequest.getObjectParameter(PARAM_PROFILE);
Output Parameters
After resolving all relevant parameters in the droplet, some backend processing is done. Make sure all the business logic is removed from the service method and placed into a helper method or class. After this processing, something can be returned back to the page. Keep in mind that output parameters are optional. In this example, an output parameter is used to display the message or error message. The droplet however could be used to control flow of the JSP. An example of this is the out of the box Switch droplet that renders different parameters depending on which value the passed in object had.
To set output parameters, use the pRequest.setParameter(String pParameterName, Object pValue) method. There isn’t anything difficult about setting output parameters. Three different parameters are set in the example droplet:
// error message
pRequest.setParameter(PARAM_ERROR_MESSAGE, “The passed in Profile was null.”);
// missing currentPage
pRequest.setParameter(PARAM_MESSAGE, MessageFormat.format(“Hello, {0}.”, name));
// has current page
pRequest.setParameter(PARAM_MESSAGE, MessageFormat.format(“Hello, {0}, thanks for visiting {1}.”, name, currentPage));
Output parameters can be retrieved using any tag of choice in the JSP. Commonly if the parameter will be used later, it is set as a page parameter:
<dsp:getvalueof param=”url” var=”someUrl”/>
Above, is a common piece of code in the ATG SiteLinkDroplet. The code takes the ‘url’ parameter set in the droplet and sets it in a ‘someUrl’ variable accessible outside of the droplet.
Parameters can also be accessed using dsp:valueof as in the example below. For any tags nested within the droplet, their param attribute can point to the parameter set in the droplet.
Error: <dsp:valueof param=”errorMsg”/>
Open Parameters
Open parameters are executed one or many times during the droplet’s processing. The Java code backing the droplet will determine which to show and when. In the example, the error open parameter was serviced when the Profile passed in was null and the output parameter was shown when processing was successful.
Open parameters are indicated in the droplet by using dsp:oparam tags as shown below.
<dsp:droplet name=”/test/droplet/SayHelloDroplet”>
<dsp:param name=”profile” bean=”/atg/userprofiling/Profile”/>
<dsp:param name=”currentPage” value=”SampleDroplet.jsp”/>
<dsp:oparam name=”output”>
<dsp:valueof param=”message”/>
</dsp:oparam>
<dsp:oparam name=”error”>
Error: <dsp:valueof param=”errorMsg”/>
</dsp:oparam>
</dsp:droplet>
To service an open parameter, call the pRequest.serviceParameter(String pOpenParamName, pRequest, pResponse) method. Remember, all parameters must be set before calling this method!
pRequest.serviceParameter(OPARAM_ERROR, pRequest, pResponse);
or
pRequest.serviceParameter(OPARAM_OUTPUT, pRequest, pResponse);
Side note:
It may be useful to display the same parameter multiple times in the same droplet. For example, you might have the task of iterating over a set of items in an order. This could be done by passing the collection back to the JSP, then using a ForEach droplet to loop through it. A cleaner approach is to simply loop through the collection in the droplet, rendering an open parameter for each iteration.
Droplet Naming Conventions
If you browse through the out of the box droplets, an unsaid naming convention is followed. Since out of the box droplets are used heavily, any custom droplets should follow the same naming guidelines.
Input parameter names are usually unique to the function of the droplet. There are just a few input parameter names reused throughout the out of the box framework:
- array – Used in droplets like ForEach for when a collection is passed into the droplet.
- howMany – Used in droplets like ForEach for specifying how many iterations are required
Output parameters also have some common names:
- element – For droplets that return an object, this is the standard way of naming
- index – 0-based current iteration count
- count – 1-based current iteration count
- errorMsg – An error message
Open parameters can be named custom, but usually they have one of the following names:
- output – This is the most common open parameter name. Use this for when the droplet’s processing went as expected.
- empty – Used when a lookup used in the backend, or a value was empty.
- error – Used to communicate an error.
- outputStart – Some out of the box droplets use this as a place to put code before the output parameter
- outputEnd – Some out of the box droplets use this as a place to put code after the output parameter
It is a great idea to stick with the out of the box naming conventions for open parameters.
Conclusion
The droplet example provided here will print out one of three messages. If the passed in Profile is null, an error message is displayed. If the user doesn’t have a first name set, their profile ID is used in place. Depending on if the currentPage parameter has been set, the correct message is displayed.
Sample DropletHello, 5200000, thanks for visiting SampleDroplet.jsp
Droplets are a strong feature to the front-end of ATG applications. Using droplets in JSPs provides the ability to easily and dynamically generate content for users. ATG comes out of the box with a big selection of droplets, but when those aren’t enough it is very easy to write a custom droplet. Custom droplets are particularly easy to implement because the API isn’t complicated.
The only advanced features not covered here are using the ParameterName class to set parameters for slightly faster performance and the concept of a local parameter versus a standard parameter. These topics are covered in detail in the ATG Programming Manual.
What are the droplets with request scope in OOTB?
You can find some of them in Appendix B of Oracle Commerce Page Developer’s Guide http://docs.oracle.com/cd/E69533_01/Platform.11-3/ATGPageDevGuide/html/index.html
Amogh,
We use a global scope in the droplet (and wherever possible in ATG) to cut down on the number of components initialized during runtime. If the droplet does not have any session or request dependencies, it should always be made global so that the application has only one instance of the droplet running.
In my experience, 99% of the time you can get away with using a globally-scoped droplet. In the case that you might need to access a request-scoped component from a droplet like the Profile or Order, you can pass it in as a parameter from the JSP and still keep the droplet global.
nice article. can you explain why we should give scope as global only for droplets? whats the impact if we change scope to request or session? thanks in advance
Hi,
there is blog i found.. which teaches atg right from scratch.. it also explains droplets in awesome way.. you can have a look:-
http://learnoracleatg.blogspot.in/2014/10/art109-what-are-droplets-or-dynamo.html
nice
Hello Peter,
the way you explained Droplets is very clear as a ATG layman I have understood it very clealry. Thanks alot. Expecting more topics on ATG.
Thanks,
Cyril T
awesome!
Its Awesome !!! Very good for beginners. Now I am able to clearly differentiate between Input, Output and Open Parameters. Thanks for the info, keep up the good work.
Just Awesome !!! Good for beginners … Its really gives the clear view of the fundamentals of droplet..
Thanks !!!
Hi Aamir,
The ATG Repository API is a huge discussion that I could not cover in just a comment. I’ve been meaning to provide a writeup on the repository API. Keep posted, I may write it soon.
hi,
thank you so much for providing this example. This is too good nad easy to understand the basic flow of ATG.
I have a request, can you please provide the example with code for how atg hits the database, mean to say that , a complete flow from jsp to service method and then to the database.
Simply how we can show the value from database to jsp page in ATG?
NIce explanation .. thank you
Input parameters and open parameters should use atg.nucleus.naming.ParameterName.getParameterName(“foo”) to really follow the established ATG droplet style. Output parameters, however, need to remain as simple strings since that uses the DynamoHttpServletRequest.setParameter method which only accepts strings.
good one
Awesome explanation…….