📄 client.java
字号:
//声明这个类属于包examples.jta.jmsjdbc
package examples.jta.jmsjdbc;
//声明这个类引入的其他类
//文件io类
import java.io.IOException;
import java.io.BufferedReader;
import java.io.InputStreamReader;
//远程方法调用异常类
import java.rmi.RemoteException;
//jdbc类
import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.Statement;
import java.sql.SQLException;
//集合类
import java.util.Hashtable;
//Ejb异常类
import javax.ejb.CreateException;
//java消息服务类
import javax.jms.JMSException;
import javax.jms.Message;
import javax.jms.Queue;
import javax.jms.QueueConnection;
import javax.jms.QueueConnectionFactory;
import javax.jms.QueueSender;
import javax.jms.QueueSession;
import javax.jms.Session;
import javax.jms.TextMessage;
//java名称服务类
import javax.naming.Context;
import javax.naming.InitialContext;
import javax.naming.NamingException;
import javax.rmi.PortableRemoteObject;
import javax.sql.DataSource;
/**
* 这个例子演示如何使用JTA执行分布式业务,事务处理的资源包括:JMS队列和数据库
* 这个例子分以下三步:
* 1、客户端发送消息到消息队列,初始化数据表,调用EJBean ReceiveInTxBean
* 2、ReceiveInTxBean 开始一个分布式事务处理:从JMS队列获取消息,更新数据库,触发分布式事务
* 3、客户端确认数据库中的数据已更新,并清除数据表
*/
public class Client {
//声明队列消息连接器类名
private static final String queueConnFactoryName="weblogic.examples.jms.QueueConnectionFactory";
//声明队列名
private static final String queueName="weblogic.examples.jms.exampleQueue";
//声明EJB主接口注册名
private static final String homeJNDIName = "jta-jmsjdbc-ReceiveInTxHome";
//声明数据源连接池名
private static final String dataSrcName = "examples-dataSource-demoPool";
//声明表明
private static final String tableName = "jtaSamples";
//声明应用服务器url
private static String url = "t3://localhost:7001";
public static void main(String[] args)
throws Exception
{
if (args.length != 1) {
//如果命令行参数不是1个,打印出用法提示:
System.out.println("用法: java examples.jta.jmsjdbc.Client WebLogicURL");
System.out.println("例如: java examples.jta.jmsjdbc.Client t3://localhost:7001");
return;
}
url = args[0];
//首先,调用方法getInitialContext,获取名称服务初始上下文(参看本类的getInitialContext方法)
//初始化上下文是下面的消息发送,数据源获取和ejb使用的基础。
InitialContext ic = getInitialContext(args[0]);
//以下是消息发送:
//声明并实例消息发送类QueueSend(参看类QueueSend)
//构造函数的参数为初始上下文、队列消息连接器类名,队列名
QueueSend qs = new QueueSend(ic, queueConnFactoryName, queueName);
//队列消息发送类初始化
qs.init();
//从命令行读取文本并作为消息发送
readAndSend(qs);
//关闭消息发送类
qs.close();
//以下是数据源操作
//声明并通过JNDI获取数据源对象实例。
DataSource ds = (DataSource) ic.lookup(dataSrcName);
//调用方法initTable,初始化数据源ds中的tableName表(参看本类的initTable方法)
initTable(ds, tableName);
//以下是EJB操作
//调用方法lookupBean,通过JNDI查找EJB远程对象(参看本类的lookupBean方法)
ReceiveInTx recv = lookupBean(ic, homeJNDIName);
//调用远程方法
recv.receiveMessages();
//以下是数据源操作
//查询表tableName(参看本类的queryDatabase方法)
queryDatabase(ds, tableName);
//删除表tableName(参看本类的qdropTable方法)
dropTable(ds, tableName);
}
//本类使用的方法
//从命令行读取文本并作为消息发送
private static void readAndSend(QueueSend qs)
throws IOException, JMSException
{
//声明并实例命令行字符输入流
BufferedReader msgStream = new BufferedReader(new InputStreamReader(System.in));
String line=null;
boolean quitNow = false;
do {
//打印提示
System.out.print("Enter message (\"quit\" to quit): ");
//读取用户输入
line = msgStream.readLine();
if (line != null && line.trim().length() != 0) {
//发送消息
qs.send(line);
log("JMS Message Sent: "+line+"\n");
//退出命令
quitNow = line.equalsIgnoreCase("quit");
}
} while (! quitNow);
}
//本类使用的方法
//做的工作是,如果名子为tableName的表不存在,则创建它
private static void initTable(DataSource ds, String tableName)
{
//声明数据库连接和SQL语句
Connection jcon = null;
Statement stmt = null;
try {
//数据源连接
jcon = ds.getConnection();
//设置此连接为自动发送模式(自动发送模式,即每个SQL语句作为独立的事务执行)
jcon.setAutoCommit(true);
//获取SQL语句对象
stmt = jcon.createStatement();
try {
//执行SQL命令:删除表tableName
stmt.execute("drop table " + tableName);
} catch (SQLException ex) {}
//执行SQL命令:创建表tableName
stmt.execute("create table " + tableName + "(data varchar(40))");
} catch (SQLException ignore) {
} finally {
//做一些清除工作,释放资源
if (stmt != null) {
try { stmt.close(); } catch (SQLException ex) {}
}
if (jcon != null) {
try { jcon.close(); } catch (SQLException ex) {}
}
}
}
//本类使用的方法
//查询表
private static void queryDatabase(DataSource ds, String tableName)
{
//声明数据库连接和SQL语句
Connection jcon = null;
Statement stmt = null;
try {
//数据源连接
jcon = ds.getConnection();
//获取SQL语句对象
stmt = jcon.createStatement();
//执行SQL命令:查询表tableName所有列
stmt.execute("select * from " + tableName);
//获取结果集并返回
ResultSet rs = stmt.getResultSet();
String data = null;
log("Data found in database:");
//打印表的第一列
while (rs.next()) {
data = rs.getString(1);
log(data);
}
} catch (SQLException ex) {
//执行SQL错误抛出的异常
log("Got SQLException while querying database: " + ex);
} finally {
//最后做一些清除工作
if (stmt != null) {
try { stmt.close(); } catch (SQLException ex) {}
}
if (jcon != null) {
try { jcon.close(); } catch (SQLException ex) {}
}
}
}
//本类使用的方法
//删除表
private static void dropTable(DataSource ds, String tableName)
{
//声明数据库连接和SQL语句
Connection jcon = null;
Statement stmt = null;
try {
//数据源连接
jcon = ds.getConnection();
//获取SQL语句对象
stmt = jcon.createStatement();
//执行SQL命令:删除表tableName
stmt.execute("drop table " + tableName);
} catch (SQLException ignore) {
} finally {
//最后做一些清除工作,关闭连接
if (stmt != null) {
try { stmt.close(); } catch (SQLException ex) {}
}
if (jcon != null) {
try { jcon.close(); } catch (SQLException ex) {}
}
}
}
//本类使用的方法
//给定名称服务上下文和名字查找远程EJB对象
private static ReceiveInTx lookupBean(InitialContext ictx, String jndiName) {
try {
//查找远程主接口对象
Object home = ictx.lookup(jndiName);
//检查类型,主接口对象应该是ReceiveInTxHome
ReceiveInTxHome rhome = (ReceiveInTxHome)
PortableRemoteObject.narrow(home, ReceiveInTxHome.class);
//创建远程对象并检查类型,远程对象应该是ReceiveInTx
ReceiveInTx bean = (ReceiveInTx)
PortableRemoteObject.narrow(rhome.create(), ReceiveInTx.class);
//返回这个EJB
return bean;
} catch (NamingException ne) {
//名称错误抛出这个异常
log("The client was unable to lookup the EJBHome. Please make sure ");
log("that you have deployed the ejb with the JNDI name "+jndiName+" on the WebLogic server at "+url);
} catch (CreateException ce) {
//创建远程EJB错误,抛出这个异常
log("Creation failed: " + ce);
} catch (RemoteException ex) {
//远程调用错误,抛出这个异常
log("Creation failed: " + ex);
}
return null;
}
//本类使用的方法
//获取名称服务初始化上下文
private static InitialContext getInitialContext(String url)
throws NamingException
{
//上下文属性设置
Hashtable env = new Hashtable();
env.put(Context.INITIAL_CONTEXT_FACTORY,
"weblogic.jndi.WLInitialContextFactory");
env.put(Context.PROVIDER_URL, url);
return new InitialContext(env);
}
//本类使用的方法
//打印
private static void log(String s) {
System.out.println(s);
}
}
/**
* 队列消息发送类:创建JMS对象,向一个消息队列中发送消息
*/
class QueueSend
{
//声明名称服务上下文变量
private InitialContext ictx;
//声明消息队列构造器名变量
private String queueConnFactoryName;
//声明队列名
private String queueName;
//声明消息队列构造器变量
private QueueConnectionFactory qconFactory;
//声明消息队列连接变量
private QueueConnection qcon;
//声明消息队列会话变量
private QueueSession qsession;
//声明消息队列发送器变量
private QueueSender qsender;
//声明消息队列变量
private Queue queue;
//声明文本消息变量
private TextMessage msg;
//构造函数
public QueueSend(InitialContext ictx,
String queueConnFactoryName, String queueName)
{
this.ictx = ictx;
this.queueConnFactoryName = queueConnFactoryName;
this.queueName = queueName;
}
/**
* 创建发送消息到JMS消息队列所需的所有对象
*
* @参数 ctx JNDI initial context.
* @参数 queueName Name of queue.
* @异常 NamingException if operation cannot be performed
* @异常 JMSException if JMS fails to initialize due to internal error
*/
public void init()
throws NamingException, JMSException
{
//通过JNDI查找消息队列构造器
qconFactory = (QueueConnectionFactory) ictx.lookup(queueConnFactoryName);
//通过消息队列构造器创建消息队列连接
qcon = qconFactory.createQueueConnection();
//通过消息队列连接创建消息队列会话
qsession = qcon.createQueueSession(false, Session.AUTO_ACKNOWLEDGE);
//通过JNDI和队列名查找消息队列
queue = (Queue) ictx.lookup(queueName);
//通过消息队列会话创建消息发送器
qsender = qsession.createSender(queue);
//通过消息队列会话创建文本消息
msg = qsession.createTextMessage();
//启动连接
qcon.start();
}
/**
* 向JMS消息队列中发送消息
*
* @参数s message Message to be sent.
* @异常 JMSException if JMS fails to send message due to internal error
*/
public void send(String message)
throws JMSException
{
//设定文本消息的文本
msg.setText(message);
//发送文本消息message
qsender.send(msg);
}
/**
* 关闭JMS对象
* @异常 JMSException if JMS fails to close objects due to internal error
*/
public void close()
throws JMSException
{
qsender.close();
qsession.close();
qcon.close();
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -