Create your own portlet service


Writing a portlet service consists of four steps:

  1. Defining the interface
  2. Writing the service implementation
  3. Making the service accessible for IBM portlets
  4. Registering the service

The service provider interfaces for writing portlet services have changed to support JSR 168 portlets. As of V5.1, service provider interfaces can be used to write portlet services for IBM portlets as well as JSR 168 portlets. For backward-compatibility, the service provider interfaces from the org.apache.jetspeed.portlet.service.spi packages are supported. For writing new portlets services, however, use only the service provider interfaces described in this text

 

Defining the interface

This step is not required if you want to implement your service against an existing interface. Defining a portlet service interface requires the same careful considerations as defining any public API interface. A portlet service interface must extend the PortletService interface defined in the com.ibm.portal.portlet.service package. The following is an example interface for the HelloWorldService .

package sample.portletservice;

import java.io.IOException;
import javax.portlet.RenderRequest;
import javax.portlet.RenderResponse;
import com.ibm.portal.portlet.service.PortletService;

public interface HelloService extends PortletService
{
    /** print a nice greeting */
    public void sayHello(RenderRequest request, RenderResponse response) throws IOException;
}

 

Writing the service implementation

The service implementation must implement the PortletServiceProvider interface of the com.ibm.portal.portlet.service.spi package to be able to make use of the portlet service life cycle methods in addition to your service interface. The PortletServiceConfig parameter of the init() method allows you, for example, to access the configuration of the service (see Registering the service for more information).


package sample.portletservice;

import java.io.IOException;
import java.io.PrintWriter;
import java.util.prefs.Preferences;

import javax.portlet.RenderRequest;
import javax.portlet.RenderResponse;

import com.ibm.portal.portlet.service.spi.PortletServiceProvider;
 
public class HelloServiceImpl 
    implements HelloService, PortletServiceProvider {
    
    private String message;
        
    // called by the portal when the service is initialized        
    public void init(Preferences servicePreferences) {
        
        // read the message from the configuration, default is "Hello"
        message = servicePreferences.get("message", "Hello");
    }
        
    public void sayHello(RenderRequest request, RenderResponse response) throws IOException {
        String user = request.getRemoteUser();
        if (user == null)
            // no user logged in
            user = "Stranger";
        
        PrintWriter out = response.getWriter();
        out.print(message);
        out.print(", ");
        out.print(user);            
    }

}

 

Making the service accessible for IBM portlets

This step is optional. If you want your portlet service to be available for IBM portlets, create an additional service interface that extends org.apache.jetspeed.portlet.service.PortletService and provides the same functionality.


package sample.portletservice;

import java.io.IOException;
import org.apache.jetspeed.portlet.PortletRequest;
import org.apache.jetspeed.portlet.PortletResponse;
import org.apache.jetspeed.portlet.service.PortletService;

public interface HelloServiceIBM extends PortletService {

    /** print a nice greeting */
    public void sayHello PortletRequest(request, PortletResponse response) throws IOException;

}

You can have a single implementation that is registered for both interfaces and implements both. If the service methods take arguments that are classes or interfaces from the portlet API, the method signatures are different for the two service interfaces. You can still use a common implementation for both interfaces by using the APIConverterFactory class of the com.ibm.portal.portlet.apiconvert package. This class includes methods that wrap objects from the IBM portlet API, such as the PortletRequest and PortletSession, and implement the corresponding Java Portlet API objects (JSR 168) on the service side, so that you can re-use your service implementation for JSR 168 portlets.


package sample.portletservice;

import java.io.IOException;
import java.io.PrintWriter;
import java.util.prefs.Preferences;

import javax.portlet.RenderRequest;
import javax.portlet.RenderResponse;

import org.apache.jetspeed.portlet.PortletRequest;
import org.apache.jetspeed.portlet.PortletResponse;

import com.ibm.portal.portlet.apiconvert.APIConverterFactory;
import com.ibm.portal.portlet.service.spi.PortletServiceProvider;
 
public class HelloServiceImpl2 
    implements HelloService, HelloServiceIBM, PortletServiceProvider {
    
    private String message;
        
    // called by the portal when the service is initialized        
    public void init(Preferences servicePreferences) {
        
        // read the message from the configuration, default is "Hello"
        message = servicePreferences.get("message", "Hello");
    }
        
    public void sayHello(RenderRequest request, RenderResponse response) throws IOException {
        String user = request.getRemoteUser();
        if (user == null)
            // no user logged in
            user = "Stranger";
        
        PrintWriter out = response.getWriter();
        out.print(message);
        out.print(", ");
        out.print(user);            
    }
    
    public void sayHello PortletRequest(request, PortletResponse response) throws IOException {
        sayHello (APIConverterFactory.getInstance().getRenderRequest(request),
            APIConverterFactory.getInstance().getRenderResponse(response));
    }

}

 

Registering the service

  1. Put all service interface and implementation classes into a JAR file.
  2. Place the JAR file in the wp_root/shared/app directory.
  3. Update the PortletServiceRegistryService.properties file in the wp_root/shared/app/config/services directory to register the new service:

    • Register the implementation in the JNDI directory. The syntax of this line is jndi:service_interface = service_implementation. The fully qualified service interface name can then be used to lookup the service.
    • If you provide a service interface for IBM portlets, register the implementation for this interface as well. The syntax for services for IBM portlets is service_interface = service_implementation. Services that are registered this way are not retrieved from JNDI, but from the PortletContext interface of the IBM portlet API.
    • Provide configuration parameters for the implementation. The syntax for configuration parameters is service_implementation.parameter=value.
    • Restart the portal server.

In the following example, HelloService is the name of the portlet service, HelloServiceIBM is the name of the interface for IBM portlets, and the message configuration parameter is set with the value Greetings.


    jndi:sample.portletservice.HelloService = sample.portletservice.HelloServiceImpl2
    sample.portletservice.HelloServiceIBM = sample.portletservice.HelloServiceImpl2
    sample.portletservice.HelloServiceImpl2.message = Greetings

Tip: To check whether your service has been registered successfully, use the appserver dumpNamespace tool. The following command, executed from the was_root/bin directory, will list all portlet service entries in JNDI:

 dumpNamespace -port bootstrap_port -root server -startAt portletservice

Using the appserver's administrative console, you can find the bootstrap port of your portal server in the "End Points" section of the settings for the server "WebSphere_Portal".

 

See also

Home |

 

WebSphere is a trademark of the IBM Corporation in the United States, other countries, or both.

 

IBM is a trademark of the IBM Corporation in the United States, other countries, or both.