Accessing remote systems


The portlet API provides a ContentAccessService , which allows portlets to access remote systems or content from remote URLs, including URLs located on the other side of a proxy server. You should always use this service to access remote content if you cannot be certain whether a firewall will be present after the portlet is deployed into a production environment.

The following example shows how to use the content access service to setup an HTTP input stream to a remote system. In this example, the method receives the URL to the backend system as a String (urlS). The URL is then checked to determine if the system is local (the isHTTPLocalhostURL() method not shown). If the URL is local, the content access service is not needed. If the URL is remote, the getURL() method is used to create a java.net.URL object and return an InputStream used to read from the remote connection.

Example: ContentAccessService



   protected InputStream getHTTPInputStream(String urlS, PortletRequest request, PortletResponse response)
                throws MalformedURLException, IOException {

      if(getPortletLog().isInfoEnabled()) {
            getPortletLog().info("getHTTPInputStream: " + urlS);
        }
                
      if(isHttpLocalhostURL(urlS)) {   //local url
          if(getPortletLog().isInfoEnabled()) {
                getPortletLog().info("getHTTPInputStream: local URL");
            }
         return(new URL(urlS)).openStream();
      }

      URL contentURL = null;

         try {
            PortletContext context = getPortletConfig().getContext();
            ContentAccessService contentAccessservice = 
               (ContentAccessService)context.getService(org.apache.jetspeed.portlet.service.ContentAccessService.class);
            contentURL = contentAccessservice.getURL( urlS, request, response );
               if(getPortletLog().isInfoEnabled()) {
                  getPortletLog().info("getHTTPInputStream: final URL" + contentURL);
               }
            return contentURL.openStream();
         } catch(PortletServiceException e) {
            getPortletLog().error("MyPortlet: ContentAccessPortletService error: ",e);
               if(getPortletLog().isErrorEnabled()) {
                  getPortletLog().error("ContentAccessService error:" + e);
               }
            throw new IOException("ContentAccessPortletService Error: " + e);
         }
   }
   

Hint: When accessing remote internet resources directly, the content is simply taken and written to the portlet's output. This means that all relative links to other pages or images will be broken. This can be solved by parsing the content or use some enhanced browser portlet.

The ContentAccessService can also open an SSL connection to remote applications. The code is the same as for nonsecure connections (see Example: ContentAccessService) except that you specify a secure protocol (HTTPS) in the URL. However, the portal must be configured to support SSL in PortletServiceRegistryService.properties (see PortletServiceRegistry Service) .

The content access service can also be used to access resources, such as JSPs and servlets, in the local portal Web application. By contrast, the PortletContext.include() method can include only JSPs local to the portlet application.

 

getMarkup and character sets

The getMarkup and include methods in ContentAccessService require a Web site to return the character set used to encode the content; this information is normally included in the HTTP response headers. However, sometimes Web sites do not specify the character set. In this case, ContentAccessService assumes the content is encoded with UTF-8. However, if the Web site contains non-English content (for example, double-byte character languages such as Japanese and Korean), content will not render properly.

Developers can work around this problem by using the getInputStream method, which handles the character set conversion manually. For example:

InputStream stream = contentAccessService.getInputStream(url, portletRequest, portletResponse);
Reader reader = new InputStreamReader(stream, mySpecifiedCharset);

See also