clienthandler.java

来自「100多M的J2EE培训内容」· Java 代码 · 共 432 行

JAVA
432
字号
package bible.jms;



import java.util.*;

import java.sql.*;

import javax.jms.*;

import javax.naming.*;

import javax.transaction.UserTransaction;


/**
 * Class ClientHandler
 *
 *
 * @author
 * @version %I%, %G%
 */
public class ClientHandler {

  // Unique client ID for
  // database operations
  private String clientID = null;

  // Data structure describing a trade
  private class Trade {

    String clientID   = null;
    String side       = null;
    String ticker     = null;
    int    shares     = 0;
    double sharePrice = 0.0;
  }

  /**
   * Constructor ClientHandler
   *
   *
   */
  public ClientHandler() {}

  /**
   * Constructor ClientHandler
   *
   *
   * @param id
   *
   */
  public ClientHandler(String id) {
    clientID = id;
  }

  // Get the WebLogic server's context

  /**
   * Method getServerContext
   *
   *
   * @return
   *
   */
  public Context getServerContext() {

    Context   ctx = null;
    Hashtable ht  = new Hashtable();

    ht.put(Context.INITIAL_CONTEXT_FACTORY,
           "weblogic.jndi.WLInitialContextFactory");
    ht.put(Context.PROVIDER_URL, "t3://localhost:7001");

    try {
      ctx = new InitialContext(ht);
    } catch (NamingException e) {
      e.printStackTrace();
    } finally {
      return ctx;
    }
  }

  // Load the queue with a single trade:
  // BUY 1000 shares BEAS at $30/share

  /**
   * Method loadQueue
   *
   *
   */
  public void loadQueue() {

    Context                ctx                = null;
    QueueConnectionFactory qConnectionFactory = null;
    QueueConnection        qConnection        = null;
    QueueSession           qSession           = null;
    QueueSender            qSender            = null;
    Queue                  q                  = null;
    TextMessage            textMsg            = null;

    try {

      // Obtain references to JMS structures
      qConnectionFactory =
        (QueueConnectionFactory) getServerContext().lookup("BibleJMSFactory");
      qConnection        = qConnectionFactory.createQueueConnection();
      qSession           = qConnection.createQueueSession(false,
        javax.jms.QueueSession.AUTO_ACKNOWLEDGE);
      q                  = (Queue) getServerContext().lookup("BibleJMSQueue");
      qSender            = qSession.createSender(q);
      textMsg            = qSession.createTextMessage();

      // Pass a human-readable trade summary
      // in the message's body
      textMsg.clearBody();
      textMsg.setText("BUY 1000 BEAS 30.0");

      // Pass essential trade data in
      // user-defined message properties
      textMsg.setStringProperty("client_id", clientID);
      textMsg.setStringProperty("side", "BUY");
      textMsg.setStringProperty("ticker", "BEAS");
      textMsg.setIntProperty("shares", 1000);
      textMsg.setDoubleProperty("sharePrice", 30.0);

      // Send the message
      qSender.send(textMsg);
    } catch (Exception e) {
      e.printStackTrace();
    } finally {
      try {
        if (qSender != null) {
          qSender.close();
        }

        if (qSession != null) {
          qSession.close();
        }

        if (qConnection != null) {
          qConnection.close();
        }
      } catch (Exception e) {}
    }
  }

  // Synchronously read a single trade from
  // the queue for the given client

  /**
   * Method getNextTrade
   *
   *
   * @return
   *
   * @throws Exception
   *
   */
  public Trade getNextTrade() throws Exception {

    QueueConnectionFactory qConnectionFactory = null;
    QueueConnection        qConnection        = null;
    QueueSession           qSession           = null;
    QueueReceiver          qReceiver          = null;
    Queue                  q                  = null;
    Trade                  trade              = null;

    try {

      // Obtain references to JMS structures
      qConnectionFactory =
        (QueueConnectionFactory) getServerContext().lookup("BibleJMSFactory");
      qConnection        = qConnectionFactory.createQueueConnection();
      qSession           = qConnection.createQueueSession(false,
        javax.jms.QueueSession.AUTO_ACKNOWLEDGE);
      q                  = (Queue) getServerContext().lookup("BibleJMSQueue");

      // Note the use of a message filter - we
      // only want the next trade for the client
      // represented by this ClientHandler instance
      qReceiver = qSession.createReceiver(q, "client_id = '" + clientID
                                          + "'");

      // Start the connection
      qConnection.start();

      // Grab the next trade, if there is one,
      // and copy its data from the message
      // properties to a Trade data structure
      TextMessage textMsg = (TextMessage) qReceiver.receiveNoWait();

      if (textMsg != null) {
        trade            = new Trade();
        trade.clientID   = clientID;
        trade.side       = textMsg.getStringProperty("side");
        trade.ticker     = textMsg.getStringProperty("ticker");
        trade.shares     = textMsg.getIntProperty("shares");
        trade.sharePrice = textMsg.getDoubleProperty("sharePrice");
      }

      // Stop the connection
      qConnection.stop();
    } catch (Exception e) {
      throw e;
    } finally {
      try {
        if (qReceiver != null) {
          qReceiver.close();
        }

        if (qSession != null) {
          qSession.close();
        }

        if (qConnection != null) {
          qConnection.close();
        }
      } catch (Exception e) {}

      return trade;
    }
  }

  // Update the cash balance remaining in
  // the client's account. Account data is
  // stored in an Oracle table. For simplicity,
  // this code handles BUY transactions only.

  /**
   * Method updateAccountBalance
   *
   *
   * @param trade
   *
   * @throws Exception
   *
   */
  public void updateAccountBalance(Trade trade) throws Exception {

    javax.sql.DataSource ds         = null;
    java.sql.Connection  conn       = null;
    PreparedStatement    statement1 = null;
    PreparedStatement    statement2 = null;
    String               sql        = null;
    double               balance    = 0.0;

    try {

      // Obtain a JDBC connection from a transaction-enabled
      // DataSource. I'm using the Oracle OCI driver
      // with two-phase commit enabled, rather than
      // the Oracle XA driver.
      ds   =
        (javax.sql.DataSource) getServerContext()
          .lookup("OracleTxDataSource");
      conn = ds.getConnection();

      // Execute a query to obtain the client's current
      // account balance from the database.
      sql        = "SELECT BALANCE FROM ACCOUNT WHERE CLIENT_ID = ?";
      statement1 = conn.prepareStatement(sql);

      statement1.setString(1, clientID);

      ResultSet resultSet = statement1.executeQuery();

      if (resultSet.next()) {
        balance = resultSet.getDouble(1);
      } else {
        Exception ex = new Exception("No such account");

        throw ex;
      }

      // Calculate the cash required to buy the stock
      double cost = trade.sharePrice * trade.shares;

      // If the client has enough money, deduct the
      // cost from their account balance and update
      // their account in the database.
      if (balance > cost) {
        balance    -= cost;
        sql        = "UPDATE ACCOUNT SET BALANCE = ? "
                     + "WHERE CLIENT_ID = ?";
        statement2 = conn.prepareStatement(sql);

        statement2.setDouble(1, balance);
        statement2.setString(2, clientID);

        if (statement2.executeUpdate() != 1) {
          Exception ex = new Exception("Error updating account balance");

          throw ex;
        }
      } else {
        Exception ex = new Exception("Insufficient funds");

        throw ex;
      }
    } catch (Exception e) {
      e.printStackTrace();

      throw e;
    } finally {
      statement1.close();
      statement2.close();
      conn.close();
    }
  }

  // Add an entry for stock purchased to
  // the client's portfolio, which is stored
  // in an Oracle table.

  /**
   * Method updatePortfolio
   *
   *
   * @param trade
   *
   * @throws Exception
   *
   */
  public void updatePortfolio(Trade trade) throws Exception {

    javax.sql.DataSource ds        = null;
    java.sql.Connection  conn      = null;
    PreparedStatement    statement = null;
    String               sql       = null;

    try {

      // Obtain a JDBC connection from a transaction-enabled
      // DataSource. I'm using the Oracle OCI driver
      // with two-phase commit enabled, rather than
      // the Oracle XA driver.
      ds   =
        (javax.sql.DataSource) getServerContext()
          .lookup("OracleTxDataSource");
      conn = ds.getConnection();

      // Execute a query to insert the client's stock
      // purchase into the portfolio table.
      sql       = "INSERT INTO PORTFOLIO "
                  + "(CLIENT_ID, SIDE, TICKER, SHARES, PRICE) "
                  + "VALUES (?, ?, ?, ?, ?)";
      statement = conn.prepareStatement(sql);

      statement.setString(1, clientID);
      statement.setString(2, trade.side);
      statement.setString(3, trade.ticker);
      statement.setInt(4, trade.shares);
      statement.setDouble(5, trade.sharePrice);

      if (statement.executeUpdate() != 1) {
        Exception ex = new Exception("Error updating client's portfolio");

        throw ex;
      }
    } catch (Exception e) {
      e.printStackTrace();

      throw e;
    } finally {
      statement.close();
      conn.close();
    }
  }

  // Method to test our example

  /**
   * Method main
   *
   *
   * @param args
   *
   */
  public static void main(String[] args) {

    UserTransaction tx = null;

    try {

      // Create a ClientHandler instance for fictitious
      // customer "joe." Load the queue with a hard-coded
      // trade for this client.
      ClientHandler ch = new ClientHandler("joe");

      ch.loadQueue();

      // Obtain a reference to WebLogic Server's context.
      // Use it to perform a JNDI lookup on the server's
      // UserTransaction object.
      Context ctx = ch.getServerContext();

      tx = (UserTransaction) ctx.lookup("javax.transaction.UserTransaction");

      // Begin the transaction
      tx.begin();

      // Grab the trade from the message queue
      Trade trade = ch.getNextTrade();

      // Update the client's account balance
      ch.updateAccountBalance(trade);

      // Update the client's portfolio
      ch.updatePortfolio(trade);

      // If no exceptions, commit the transaction
      tx.commit();
    } catch (Exception e) {
      try {

        // Something went wrong... roll back
        // the transaction
        tx.rollback();
      } catch (Exception ee) {
        ee.printStackTrace();
      }
    }
  }
}


/*--- Formatted in Bible Style on Thu, Sep 6, '01 ---*/


/*------ Formatted by Jindent 3.24 Gold 1.02 --- http://www.jindent.de ------*/

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?