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 + -
显示快捷键?