Working through the first steps of this tutorial has given you a sense of how a Java control works. In ideal conditions, it does what it is supposed to do. But as it now stands, it isn't quite ready for prime time. Here are a few possible problems:
You have no way of knowing how long it will take the credit card service to respond to your requests. To better manage this, you can use a timer to set a limit on how the resource may take to respond.
Below you will enhance the Investigate Java control to better handle these possible problems.
This tasks in this step are:
/** * @common:operation */ public void cancelInvestigation() { /* * Cancel the request to the credit card company because it is now unnecessary. */ creditCardReportControl.cancelRequest(); /* * Use the callback to send a message to the client. Note that this also ends * the conversation because the callback's conversation phase property is set to "finish". */ m_currentApplicant.message = "Investigation canceled."; callback.onCreditReportDone(m_currentApplicant); }
To Add a Timer Control to Limit the Time Allowed for Response
It can be difficult to predict how long an asynchronous resource will take to respond to a request. For example, Investigate's call to the credit card report web service may take hours. Here, you will add a way to limit the amount of time the credit card's web service has to respond. Using a Timer control, you can specify an amount of time after which the operation should be canceled.
public void requestCreditReport(String taxID) { m_currentApplicant.taxID = taxID; /** * Retrieve data from the database and store it in the rec object. */ Record rec = bankruptciesDB.checkForBankruptcies(taxID); /** * If the database returns substantial data, then store that data * in the m_currentApplicant object. */ if(rec != null) { m_currentApplicant.firstName = rec.firstname; m_currentApplicant.lastName = rec.lastname; m_currentApplicant.currentlyBankrupt = rec.currentlyBankrupt; /** * Invoke the Credit Card Report web service. * Results from the web service will be provided via a callback. */ creditCardReportControl.getCreditCardData(taxID); /* * Start the timer. If the credit card report is not * received within 5 minutes, the conversation will be finished * and the client will be notified that * there was a problem. */ creditCardReportTimer.start(); } /** * If the database does not return substantial data, notify the client * that there is a problem. */ else { m_currentApplicant.message = "No data could be found on the applicant. Please call (555) 555-5555 for assistance. "; /* * Send the error message to the client via a callback. */ callback.onCreditReportDone(m_currentApplicant); } }
public void creditCardReportControl_onCreditCardDataReady(java.lang.String cardData) { /* * Stop the timer that was started when the Credit Card Report web service * was called, because the callback from the web service has been received. */ creditCardReportTimer.stop(); try { /* * When a report is delivered, extract the relevant credit card info, * and store it in m_currentApplicant */ CreditCardDataDocument cardInfo = CreditCardDataDocument.Factory.parse(cardData); CustomerType[] customer = cardInfo.getCreditCardData().getCustomerArray(); CardType[] cards = customer[0].getCardArray(); for(int i = 0; i < cards.length; i++) { m_currentApplicant.availableCCCredit += cards[i].getAvailableCredit(); } } catch(XmlException xe) { /* * If there is a problem with extracting the credit card info, * store an error message in m_currentApplicant. */ m_currentApplicant.message = "There was an error retrieving the credit card information. Please call (555) 555-5555 for assistance."; /* * Send the the error message back to the client. */ callback.onCreditReportDone(m_currentApplicant); } /* * Construct and send an XML message through the JMS control * to the credit scoring application. */ String messageToJMSControl = makeMessageToJMS(m_currentApplicant.availableCCCredit, m_currentApplicant.currentlyBankrupt); creditScoreJMS.subscribe(); creditScoreJMS.sendTextMessage(messageToJMSControl); }
public void creditCardReportTimer_onTimeout(long time) { /** * Because the Credit Card Report web service has not calledback in the time allowed, * cancel the request for a report from the web service */ creditCardReportControl.cancelRequest(); /** * Cancel the current investigation. */ cancelInvestigation(); }
To Handle Exceptions Thrown from Operation Methods
Unhandled exceptions thrown from operations (such as methods exposed to clients) can leave the client hanging and the Java control may simply continue operating on the system, unnecessarily using resources.
In this step, you will add code to implement a handler for the ControlContext.onException callback. The callback handler receives the exception object thrown from the operation, the name of the method that threw the exception, and the parameters passed to the method.
WebLogic Workshop provides a way for you to preserve information about exceptions by logging it in a text file. You will add exception handling code to log the exception, then send an appropriate response to the client.
import com.bea.wlw.util.Logger;
/** * @common:context */ ControlContext context;
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 its messages * 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. * The message will be written to the jws.log file located * in the server root folder, in this case: * BEA_HOME/weblogic81/samples/domains/workshop */ logger.error("Exception in " + methodName + ": " + e); /* * Send a callback to the client with notification that an error has occurred. */ m_currentApplicant.message = "Unable to respond to request at this time. Please contact us at (555) 555-5555."; callback.onCreditReportDone(m_currentApplicant); }
By default the log file is located in the server's domain root folder, in this case the Workshop domain root folder:
BEA_HOME/weblogic81/samples/domains/workshop/workshop.log
An entry in the log will resemble the following:
21 Aug 2003 16:38:26,610 ERROR *** Investigate ***: Exception in requestCreditReport: com.bea.control.ServiceControlException: SERVICE FAULT: Code:java.io.FileNotFoundException String:Response: '401: Unauthorized xxx' for url: 'https://weblogic:wrong_password@localhost:7002/CreditCardReport_JCSTutorial/webservice/CreditCardReport.jws' Detail: END SERVICE FAULT [ServiceException]
To test the Investigate Java Control
Try the following test scenarios through InvestigateTest.jws.