Pages

30 July, 2013

A Java proxy for MS SQL Server Reporting Services:

A Java Web application often uses a SQL Server database. SQL Server now comes bundled with a reporting tool, Reporting Services. RS has generated a lot of attention among developers since it first came on the market about a year ago. It is a full-featured reporting tool that includes a WYSIWYG report editor with scripting/programming capabilities, a delivery engine, and a powerful Web services interface. Using RS makes sense—not only from a cost perspective, but also because of the reduced development and deployment complexities compared with using a third-party vendor. This article explores such an integration scenario.

 For detailed explanation and  step by step understanding purpose please go through the below URL.  

http://www.javaworld.com/javaworld/jw-01-2005/jw-0110-sqlrs.html

 Sample Code :

1. First Create a servlet name as GetReportItem..

package com.shekarsana;
import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.Authenticator;
import java.net.HttpURLConnection;
import java.net.URL;
import java.util.Enumeration;
import javax.servlet.ServletConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import util.ReportAuthenticator;

public class GetReportItem extends HttpServlet
{
    private static final long serialVersionUID = 1L;
    private final static boolean DEBUG = true;
    private final static String REPORT_SERVER_URL = "http://servername/ReportServer";
     private final static int BUFFER_SIZE = 2048;

    public void init(ServletConfig config) throws ServletException
    {
    super.init(config);
    }
    public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException
    {
    doGet(request, response);
    }

    public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException
    {
    try
    {
              String queryString = request.getQueryString();

        if (queryString.indexOf("cookie=") == -1)
        {
            System.out.println("\nGetReportItem - ERROR: No cookie parameter provided. Aborting.");
        return;
        }

        String cookie = queryString.substring(queryString.indexOf("cookie"), queryString.indexOf("&") + 1);

        queryString = queryString.replaceAll(cookie, "");
        cookie = cookie.substring(cookie.indexOf("=") + 1, cookie.length() - 1);

        String urlString = REPORT_SERVER_URL + "?" + queryString;

        if (DEBUG)
        {
        System.out.println("\nGetReportItem - Cookie: " + cookie);
        System.out.println("GetReportItem - Query String: " + queryString);
        System.out.println("GetReportItem - Send to URL: " + urlString);
        }

        if (queryString == null)
        {
                ServletOutputStream responseErrorStream = response.getOutputStream();
        responseErrorStream.println("GetReportItem - ERROR: No parameters have been provided.");
        responseErrorStream.close();
        return;
        }
        URL url = new URL(urlString);
        HttpURLConnection repCon = (HttpURLConnection) url.openConnection();
        Authenticator.setDefault(new ReportAuthenticator());
        repCon.setRequestMethod("GET");
        repCon.setRequestProperty("User-Agent", "Mozilla/5.0");
        repCon.setRequestProperty("Cookie", cookie);
        repCon.setUseCaches(false);
        repCon.setFollowRedirects(false);

        // Pipe Report Server's Output to the client using buffered streams.
        response.setContentType(repCon.getContentType());
        response.setHeader("Content-disposition", repCon.getHeaderField("Content-disposition"));
        InputStream repInStream = repCon.getInputStream();
        ServletOutputStream clientOutStream = response.getOutputStream();

        BufferedInputStream bis = new BufferedInputStream(repInStream);
        BufferedOutputStream bos = new BufferedOutputStream(clientOutStream);

        byte[] buff = new byte[BUFFER_SIZE];
        int bytesRead;

        while (-1 != (bytesRead = bis.read(buff, 0, BUFFER_SIZE)))
        {
        bos.write(buff, 0, bytesRead);
        }
        bis.close();
        bos.close();
        repInStream.close();
        clientOutStream.close();
    }
    catch (Exception e)
    {
        e.printStackTrace();
    }
    }

}

Step2 :


2.  Create a servlet name as ReportRequest.

package com.shekarsana;

import java.io.*;
import java.net.*;
import java.util.*;
import javax.servlet.*;
import javax.servlet.http.*;
import util.ReportAuthenticator;
import util.GetAvailableParameters;

public class ReportRequest extends HttpServlet
{
    private final static boolean DEBUG = true;
    private final static String REPORT_SERVER_URL = "http://ServerName/ReportServer";
    private final static String REPORT_PATH = "%2fMYReports%2f";
    private final static String REPORT_ITEM_SERVLET_URL = "http://localhost:8080/SANA/GetReportItem"
    private final static int BUFFER_SIZE = 2048;

    public void init(ServletConfig config) throws ServletException
    {
        super.init(config);
    }

    public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException
    {
        try
        {
            if(DEBUG)
            {
                System.out.println("\nInitializing Report Request");
                System.out.println("---------------------------");
            }

            Authenticator.setDefault(new ReportAuthenticator());

            // Generate parameter string from request
            String parameterString = "rs:Command=Render&rc:Toolbar=false";

            // Get the list of parameters that can be defined by the user.
            ArrayList availableParams = GetAvailableParameters.getParameters();

            Enumeration paramEnum = request.getParameterNames();

            String currentParam;
            while(paramEnum.hasMoreElements())
            {
                currentParam = (String)paramEnum.nextElement();
                if(availableParams.contains(currentParam))
                {
                    // If parameter is available, add it to the string.
                    parameterString += "&" + currentParam + "=" + request.getParameter(currentParam);
                }
            }

            String reportName = request.getParameter("reportName");

            if(DEBUG)
            {
                System.out.println("ReportRequest - Parameter String: " + parameterString);
                System.out.println("ReportRequest - Report retrieved: " + reportName);
            }

            if (reportName == null)
            {
                // Bail out if no report name is found.
                ServletOutputStream responseErrorStream = response.getOutputStream();
                responseErrorStream.println("ERROR: No report name specified");
                responseErrorStream.close();
                return;
            }

            // Establish HTTP POST connection to report server
            String urlString = REPORT_SERVER_URL + "?" + REPORT_PATH + reportName;
            URL url = new URL(urlString);

            HttpURLConnection repCon = (HttpURLConnection)url.openConnection();

            repCon.setRequestMethod("POST");
            repCon.setDoOutput(true);
            repCon.setUseCaches(false);
            repCon.setFollowRedirects(false);
            repCon.setRequestProperty("User-Agent", "Mozilla/5.0");
            repCon.setRequestProperty("Content-type", "application/x-www-form-urlencoded" );
            repCon.setRequestProperty("Content-length", Integer.toString(parameterString.length()));

            // Send parameter string to report server
            PrintWriter repOutStream = new PrintWriter(repCon.getOutputStream());

            repOutStream.println(parameterString);
            repOutStream.close();

            // Pipe Report Server's Output to the client
            forwardResponse(repCon, response);
        }
        catch (Exception e)
        {
            e.printStackTrace();

            // Alert the client there has been an error.
            ServletOutputStream responseErrorStream = response.getOutputStream();
            responseErrorStream.println("There has been an error.  Please check the system log for details.");
            responseErrorStream.close();
        }
    }

    public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException
    {
        // Redirect HTTP GET requests to doPost.
        doPost(request, response);
    }

    private void forwardResponse(HttpURLConnection reportCon, HttpServletResponse clientResponse) throws ServletException, IOException
    {
        // Take the report server's response and forward it to the client.

        String cookie = reportCon.getHeaderField("Set-Cookie");

        if(cookie == null)
        {
            System.out.println("ReportRequest - ERROR: No cookie provided by report server.  Aborting.");
            return;
        }

        if(cookie.indexOf(";") != -1)
        {
            cookie = cookie.substring(0,cookie.indexOf(";"));
        }
        if(DEBUG)
        {
            System.out.println("ReportRequest - Cookie: " + cookie);
        }

        String contentType = reportCon.getContentType();

        clientResponse.setContentType(contentType);
        clientResponse.setHeader("Content-disposition", reportCon.getHeaderField("Content-disposition"));

        InputStream repInStream = reportCon.getInputStream();
        ServletOutputStream clientOutStream = clientResponse.getOutputStream();

        if(!contentType.equals("text/html"))
        {
            // Use a buffered stream to send all binary formats.
            BufferedInputStream bis = new BufferedInputStream(repInStream);
            BufferedOutputStream bos = new BufferedOutputStream(clientOutStream);

            byte[] buff = new byte[BUFFER_SIZE];
            int bytesRead;

            while(-1 != (bytesRead = bis.read(buff, 0, BUFFER_SIZE)))
            {
                bos.write(buff, 0, bytesRead);
            }
            bis.close();
            bos.close();
        }
        else
        {
            /*
             * Use a character stream to send HTML to the client, replacing
             * references to the reporting server with the GetReportItem
             * servlet.
             */

            String currentWindow = "";
            int itemsFound = 0;

            for(int ch;(ch = repInStream.read()) != -1;)
            {
                if(currentWindow.length() < REPORT_SERVER_URL.length())
                {
                    currentWindow += (char)ch;
                }
                else if(currentWindow.equalsIgnoreCase(REPORT_SERVER_URL) && (char)ch == '?')
                {
                    itemsFound++;

                    clientOutStream.print(REPORT_ITEM_SERVLET_URL + "?cookie=" + cookie + "&");
                    currentWindow = "";
                }
                else
                {
                    clientOutStream.print(currentWindow.charAt(0));
                    currentWindow = currentWindow.substring(1) + (char)ch;
                }
            }
            clientOutStream.print(currentWindow);

            if(DEBUG)
            {
                System.out.println("ReportRequest - " + itemsFound + " references to the report server found.");
            }
        }

        repInStream.close();
        clientOutStream.close();
    }
}

Create Java Classes named as :

 GetAvailableParameters and ReportAuthenticator

Structure: 1. util/ GetAvailableParameters

and 2. util/ ReportAuthenticator

In ReportAuthenticator  Class we need to provide the Credentials:

   private String username = "shekar";
    private String password = "Sana";

Thanks 

SANA




4 comments:

  1. Hi Shekar,
    I am having issues implementing the sample code. I am running MS SQL Server 2008 and when I run the code I get ERROR: No cookie provided by report server. Aborting. Please what am I doing wrong.

    ReplyDelete
  2. Hi Shekar,

    I am also getting the same error, please help

    ReplyDelete