Step 8: Client Application

In this step you will build a Java console client to invoke your web service. Although your web service is currently designed to support a client capable of receiving callbacks, building a client that can receive callbacks is beyond the scope of this tutorial. As an alternative, you will modify your web service to support a polling interface. That is, you will modify your web service so that a client can periodically make requests to, or poll, the web service for the results.

The tasks in this step are:

- To modify your web service to support a polling interface

- To save the web service's proxy classes

- To edit the BEA_HOME and PATH environmental variables

- To compile and run the Java client application

To Modify the Web Service to Support a Polling Interface

In this section, you will add a new member variable to your web service called m_isInvestigationComplete so that your web service will know when it is time to provide the complete results to the Java client. This member variable records whether the web service has completed its task of building a credit profile of an applicant. When m_isInvestigationComplete is false, the web service returns a null response each time the Java client polls for information. Once m_isInvestigation is true, the web service returns a full profile of the credit applicant to the Java client poll.

1. If you are not in Design View, click the Design View tab.

2. Right-click Member Variables and select Add Member Variable, as shown below.

The New Member Variable dialog appears.

3. In the Variable name field, type m_isInvestigationComplete, as shown below.

4. Confirm that the value in the Type drop-down list is boolean, as shown below.

5. Click OK.

6. Right-click Member Variables and select Add Member Variable. The New Member Variable dialog appears.

7. In the Variable name field type m_callbackURL and in the Type drop-down list select String, as shown below.

8. Click OK.

9. Click requestCreditReportAsync. The requestCreditReportAsync code appears in Source View.

10. Edit requestCreditReportAsync so it appears as shown below.

        public void requestCreditReportAsynch(String taxID, boolean useCallbacks)
            throws java.sql.SQLException
        {
            if(useCallbacks)
            {
                m_callbackURL = context.getCallbackLocation();
            }
            /*
             * Query the database via the database control
             */
            Applicant dbApplicant = bankruptciesDB.checkForBankruptcies(taxID);
            /*
             * If the database contains data on the current applicant,
             * assign the retrieved values to m_currentApplicant.
             */
            if(dbApplicant != null)
            {
                m_currentApplicant = dbApplicant;
                creditCardReportControl.getCreditCardData(taxID);
                creditCardReportTimer.start();
            }
            /*
             * If the database contains no data on the current applicant,
             * inform the client.
             */
            else
            {
                /*
                 * If the member variable m_callbackURL has value other than null,
                 * then send a message to the client via the callback
                 */
                if( m_callbackURL != null )
                {
                callback.onCreditReportDone(null, "No bankruptcy data found on applicant " + taxID + ".");
                }
                /*
                 * If the member variable m_callbackURL has the value null,
                 * then the client cannot accept callbacks.
                 * Make the message available to the client through the synchronous method
                 * checkForResults.
                 */
                else
                {
                   /*
                    * Mark the investigation as complete by setting the isInvestigationComplete
                    * field to "true".  Client's that cannot accept callbacks will call checkForResults
                    * to poll for investigation results; m_isInvestigationComplete is used to determine
                    * what checkForResults should return.
                    */
                    m_isInvestigationComplete = true;
                    m_currentApplicant.approvalLevel = "No bankruptcy data found on applicant " + taxID + ".";
                }
            }
        }

11. If you are not in Design View already, click the Design View tab. Click receiveMessage (the callback handler on the JMS control). The creditScoreJWS_receiveMessage code appears in Source View.

12. Edit the code so it appears as shown below:

        private void creditScoreJMS_receiveMessage(int score)
            throws java.rmi.RemoteException
        {
            m_currentApplicant.creditScore = score;
            /*
             * Pass the credit score to the EJB's validate method. Store the value returned
             * with other applicant data.
             */
            m_currentApplicant.approvalLevel = validateCreditEJB.validate(m_currentApplicant.creditScore);
            /*
             * If the member variable m_callbackURL has value other than null,
             * then send a message to the client via the callback
             */
            if( m_callbackURL != null )
            {
            callback.onCreditReportDone(m_currentApplicant, "Credit score received.");
            }             /*
             * If the member variable m_callbackURL has the value null,
             * then the client cannot accept callbacks.
             * Make the message available to the client through the synchronous method
             * checkForResults.
             */
            else
            {
                /*
                 * Mark the investigation as complete by setting the isInvestigationComplete
                 * field to "true".  Client's that cannot accept callbacks will call checkForResults
                 * to poll for investigation results; m_isInvestigationComplete is used to determine
                 * what checkForResults should return.
                 */
                m_isInvestigationComplete = true;
            }
        }

13. If you are not in Design View already, click the Design View tab. Click cancelInvestigation. The cancelInvestigation code appears in Source View.

14. Edit the code so it appears as shown below:

        public void cancelInvestigation()
        {
            /* Cancel the request to the credit card company because it is now unnecessary.*/
            creditCardReportControl.cancelRequest();
            /*
             * If the member variable m_callbackURL has a value other than null,
             * then send a message to the client via the callback
             */
            if( m_callbackURL != null )
            {
                callback.onCreditReportDone(null, "Investigation canceled at client's request.");
            }
            /*
             * If the member variable m_callbackURL has the value null,
             * then the client cannot accept callbacks.
             * Make the message available to the client through the synchronous method
             * checkForResults.
             */
            else
            {
               /*
                * Mark the investigation as complete by setting the isInvestigationComplete
                * field to "true".  Client's that cannot accept callbacks will call checkForResults
                * to poll for investigation results; m_isInvestigationComplete is used
                * to determine what checkForResults should return.
                */
                m_isInvestigationComplete = true;
                m_currentApplicant.approvalLevel = "Investigation canceled at client's request.";
            }
        }

15. If you are not in Design View already, click the Design View tab. Click onTimeout. The creditCardReportTimer_onTimout code appears in Source View.

16. Edit the code so it appears as shown below:

        private void creditCardReportTimer_onTimeout(long time)
        {
            /* Because the credit card service has not yet returned, cancel the request.*/
            creditCardReportControl.cancelRequest();
            /*
             * If the member variable m_callbackURL has a value other than null,
             * then send a message to the client via the callback
             */
            if( m_callbackURL != null )
            {
                callback.onCreditReportDone(null, "Unable to retrieve credit card information.");
            }
            /*
             * If the member variable m_callbackURL has the value null,
             * then the client cannot accept callbacks.
             * Make the message available to the client through the synchronous method
             * checkForResults.
             */
            else
            {
               /*
                * Mark the investigation as complete by setting the isInvestigationComplete
                * field to "true".  Clients that cannot accept callbacks will call checkForResults
                * to poll for investigation results; m_isInvestigationComplete is used to determine
                * what checkForResults should return.
                */
                m_isInvestigationComplete = true;
                m_currentApplicant.approvalLevel = "Unable to retrieve credit card information.";
            }
        }

17. Click the Source View tab. Immediately beneath the Source View tab, from the class drop-down list, select context, as shown here:

18. To the right of the class drop-down list, from the member drop-down list, select onException, as shown here:
    The source code for the JwsContext onException callback handler appears.

19. Edit the code so it appears as shown below:

        public void context_onException(Exception e, String methodName, Object[] arguments)
        {
            /* Create a logger variable to use for logging messages. Assigning it the
             * "Investigate" category name will make it easier to find messages from this
             * service in the log file. */
            Logger logger = context.getLogger("Investigate");
            /* Log an error message, giving the name of the method that threw the
             * exception and a stack trace from the exception object. */
            logger.error("Exception in " + methodName + ": " + e);
            /*
             * If the member variable m_callbackURL has a value other than null,
             * then send a message to the client via the callback
             */
            if( m_callbackURL != null )
            {
                callback.onCreditReportDone(null, "Unable to respond to request at this time. " +
                                            "Please contact us at 555-5555.");
            }
            /*
             * If the member variable m_callbackURL has the value null,
             * then the client cannot accept callbacks.
             * Make the message available to the client through the synchronous method
             * checkForResults.
             */
            else
            {
               /*
                * Mark the investigation as complete by setting the isInvestigationComplete
                * field to "true".  Client's that cannot accept callbacks will call checkForResults
                * to poll for investigation results; m_isInvestigationComplete is used to determine
                * what checkForResults should return.
                */
                m_isInvestigationComplete = true;
                m_currentApplicant.approvalLevel = "Unable to respond to request at this time. " +
                                            "Please contact us at 555-5555.";
            }
        }

20. Add the following method to the web service. You can add this method by copying and pasting the code directly into Source View.

        /**
         * @jws:operation
         * @jws:conversation phase="continue"
         */
        public Applicant checkForResults()
        {  /*
            * Clients that do not support callbacks can invoke this method to receive complete results
            * on a credit applicant.         * This method will return null if the Investigate web service has not completed its profile
            * of an applicant.  It will return a full profile on an applicant once the web service has
            * completed its investigation.
            */
            Applicant retval = null;
            if(m_isInvestigationComplete == true){
                retval = m_currentApplicant;
                context.finishConversation();
            }
            return retval;
        }

21. Press Ctrl+S to save Investigate.jws.

To Save the Web Service Proxy Classes

In this task, you will save a JAR file (Java Application Archive file) that forms an interface between your web service and the Java console client. This JAR file contains Java classes that form a proxy of your web service, a proxy through which your client can invoke the actual web service.

1. Press F5 to compile your web service. Your web browser launches Test View.

2. In the browser window showing Test View there are five tabs at the top of the screen: Overview, Consol, Test Form, Test XML, and Warnings. Click the Overview tab.

3. Under Web Service Clients, click Java Proxy, as shown here:

The File Download dialog appears, as shown here:

4. Click Save. The Save As dialog appears.

5. In the Save in drop-down list, navigate to
   BEA_HOME\weblogic700\samples\workshop\applications\samples\WEB-INF\lib
   Note: BEA_HOME refers to the directory where you installed WebLogic Server 7.0. If you installed WebLogic Server 7.0 to C:\bea, then navigate to
   C:\bea\weblogic700\samples\workshop\applications\samples\WEB-INF\lib

6. In the Save as type drop-down list, make sure that All Files is selected, as shown here:

7. Click Save to save Investigate.jar. The Download Complete dialog appears.

8. Click Close.

To Set the BEA_HOME and PATH Environmental Variables

In this step you will set the paths to two environmental variables. Setting these two variables ensures that your machine can find the program that will compile your Java client application.

1. Open a command prompt window.

2. Determine the directory where you installed WebLogic Server 7.0. If you did not explicitly specify an installation directory when you installed WebLogic Server 7.0, then your installation directory is C:\bea.

3. At the command prompt, type the following command. Make sure to substitute the installation directory in place of [BEA installation directory]. For example, if you installed WebLogic Server 7.0 to C:\bea, then you would type set BEA_HOME=C:\bea

    set BEA_HOME=[BEA installation directory]

4. Press enter.
5. At the command prompt, type the following command.

    set PATH=%PATH%;%BEA_HOME%\jdk131_03\bin

This command ensures that your machine can find the program that compiles the Java client application.

6. Press Enter.

To Compile and Run the Java Client Application

Now that the JAR files are in place and the environmental variables have been set you are ready to compile and run the Java client application.

1. Using the same command window, at the command prompt, type the following command:

    cd %BEA_HOME%\weblogic700\samples\workshop\applications\samples\tutorials\java_client

2. Press Enter.

3. To compile the Java console client, type the following command:

    compile

4. Press Enter.

5. To run the Java console client, type the following command:

    run

6. Press Enter.

7. When you are prompted to enter a tax identification number, type one of the following 9 digit numbers:

    123456789, 111111111, 222222222, 333333333, 444444444, 555555555

8. Press Enter.

The client now polls the web service every second until the credit report is ready. Once it is ready, the Java console application displays the results.

Note: you may a get warning that your client does not support callbacks. You can ignore this warning because the Java console client does not rely on receiving the web service response as a callback.

Click one of the following arrows to navigate through the tutorial.