EJB 2.0之Session Bean 示例教程

本示例是在Weblogic的示范example中进行修改的,模拟Trade的buy和sell的过程.

定义了四个Business方法,具体看Remote接口Trader.

另外定义了一个testLocal的方法用来测试Local接口(为什么要这么做,不明白的同学先看看Local的基本知识)

自定义买卖过程中出现的Exceptioin:ProcessingErrorException

封装买卖的结果PO:TradeResult

模拟客户端的买卖行为:Client

配置ejb-jar.xml和weblogic-ejb-jar.xml

 1.Remote 接口 Trader.java

import java.rmi.RemoteException;
import javax.ejb.EJBObject;

public interface Trader extends EJBObject {
	public abstract TradeResult buy(String customerName, String stockSymbol,
			int shares) throws ProcessingErrorException, RemoteException;

	public abstract TradeResult sell(String customerName, String stockSymbol,
			int shares) throws ProcessingErrorException, RemoteException;

	public abstract double getBalance() throws RemoteException;

	public abstract double getStockPrice(String stockSymbol)
			throws ProcessingErrorException, RemoteException;
	
	public abstract double testLocal() throws RemoteException;
}

 2.Home 接口 TraderHome.java

import java.rmi.RemoteException;

import javax.ejb.CreateException;
import javax.ejb.EJBHome;
import javax.ejb.EJBObject;

public interface TraderHome extends EJBHome {

	public Trader create() throws RemoteException,CreateException;
}

 

3.Local 接口 TraderLocal.java

import javax.ejb.EJBLocalObject;

public interface TraderLocal extends EJBLocalObject{

	public abstract TradeResult buy(String customerName, String stockSymbol,
			int shares) throws ProcessingErrorException;
	
	public abstract TradeResult sell(String customerName, String stockSymbol,
			int shares) throws ProcessingErrorException;
	
	public abstract double getBalance() ;
	
	public abstract double getStockPrice(String stockSymbol)
	throws ProcessingErrorException;
	
	public abstract double testLocal();
}

 

4.LocalHome 接口 TraderLocalHome.java

import javax.ejb.CreateException;
import javax.ejb.EJBLocalHome;

public interface TraderLocalHome extends EJBLocalHome {
	public TraderLocal create() throws CreateException;
}

 

5.Stateful Session Bean TraderBean.java

import javax.ejb.CreateException;
import javax.ejb.RemoveException;
import javax.ejb.SessionBean;
import javax.ejb.SessionContext;
import javax.naming.Context;
import javax.naming.InitialContext;
import javax.naming.NamingException;

public class TraderBean implements SessionBean {

	static final boolean VERBOSE = true;

	private SessionContext ctx;
	private Context environment;
	private double tradingBalance;

	public void setSessionContext(SessionContext ctx) {
		log("setSessionContext called");
		this.ctx = ctx;
	}

	public void ejbActivate() {
		log("ejbActivate called");
	}

	public void ejbPassivate() {
		log("ejbPassivate called");
	}

	public void ejbRemove() {
		log("ejbRemove called");
	}

	public void ejbCreate() throws CreateException {
		log("ejbCreate called");
		try {
			InitialContext ic = new InitialContext();
			environment = (Context) ic.lookup("java:comp/env");
			
			
		} catch (NamingException ne) {
			throw new CreateException("Could not look up context");
		}
		this.tradingBalance = 0.0;
	}

	public TradeResult buy(String customerName, String stockSymbol, int shares)
			throws ProcessingErrorException {
		log("buy (" + customerName + ", " + stockSymbol + ", " + shares + ")");

		double price = getStockPrice(stockSymbol);
		tradingBalance -= (shares * price); // subtract purchases from cash
											// account

		return new TradeResult(shares, price, TradeResult.BUY);
	}

	public TradeResult sell(String customerName, String stockSymbol, int shares)
			throws ProcessingErrorException {
		log("sell (" + customerName + ", " + stockSymbol + ", " + shares + ")");

		double price = getStockPrice(stockSymbol);
		tradingBalance += (shares * price);

		return new TradeResult(shares, price, TradeResult.SELL);
	}

	public double getBalance() {
		return tradingBalance;
	}

	public double getStockPrice(String stockSymbol)
			throws ProcessingErrorException {
		try {
			return ((Double) environment.lookup(stockSymbol)).doubleValue();
		} catch (NamingException ne) {
			throw new ProcessingErrorException("Stock symbol " + stockSymbol
					+ " does not exist");
		} catch (NumberFormatException nfe) {
			throw new ProcessingErrorException("Invalid price for stock "
					+ stockSymbol);
		}
	}
	
	public double testLocal(){
		Double balance=1.00;
		try{
		InitialContext ic = new InitialContext();
		
		TraderLocalHome localHome=(TraderLocalHome)ic.lookup("ejb/TraderEJB");
		TraderLocal localTrader = (TraderLocal) localHome.create();
		balance=localTrader.getBalance();
		localTrader.remove();
		
		}catch(Exception e){
			log("local exception");
		}
		return balance;
	}

	private void log(String s) {
		if (VERBOSE) {
			System.out.println(s);
		}
	}
}

 

6.自定义Exception:ProcessingErrorException

public class ProcessingErrorException extends Exception {
  public ProcessingErrorException() {}
  public ProcessingErrorException(String message) {super(message);}
}

 

7.Trade买卖结果封装的POJO:TradeResult

import java.io.Serializable;

public final class TradeResult implements Serializable {

  public static final int SELL = 0;
  public static final int BUY  = 1;

  private int    numberTraded;    // Number of shares really bought or sold
  private int    action;          // Whether shares were bought or sold
  private double price;           // Price shares were bought or sold at

  public TradeResult(int numberTraded, double price, int action) {
    this.numberTraded = numberTraded;
    this.price        = price;
    this.action       = action;
  }

  public int getNumberTraded() {
    return numberTraded;
  }

  public int getActionTaken() {
    return action;
  }

  public double getPrice() {
    return price;
  }

  public String toString() {
    String result = numberTraded + " shares";
    if(action == SELL) {
      result += "sold";
    } else {
      result += "bought";
    }
    result += " at a price of " + price;
    return result;
  }
}

 

8.客户端调用EJB的程序:Client.java

import java.rmi.RemoteException;
import java.util.Hashtable;
import javax.ejb.CreateException;
import javax.ejb.RemoveException;
import javax.naming.Context;
import javax.naming.InitialContext;
import javax.naming.NamingException;
import javax.rmi.PortableRemoteObject;

public class Client {
	private static final String JNDI_NAME = "ejb20-statefulSession-TraderHome";
	private String url;
	private TraderHome home;

	public Client(String url) {
		this.url = url;
	}

	public static void main(String[] args) throws Exception {
		log("\nBeginning statefulSession.Client...\n");
		String url = "t3://localhost:7001";
		Client client = null;

		// Parse the argument list
		if (args.length > 1) {
			log("Usage: java examples.ejb.ejb20.basic.statefulSession.Client t3://hostname:port");
			return;
		} else if (args.length == 1) {
			url = args[0];
		}

		try {
			client = new Client(url);
			client.example();// remote
		} catch (NamingException ne) {
			log("Unable to look up the beans home: " + ne.getMessage());
			throw ne;
		} catch (Exception e) {
			log("There was an exception while creating and using the Trader.");
			log("This indicates that there was a problem communicating with the server: "
					+ e);
			throw e;
		}
		log("\nEnd statefulSession.Client...\n");
	}

	public void example() throws CreateException, ProcessingErrorException,
			RemoteException, RemoveException, NamingException {
		String customerName = "Matt";

		// Create a Trader
		log("Creating trader\n");
		home = lookupHome();
		Trader trader = (Trader) narrow(home.create(), Trader.class);

		// Sell some stock
		String stockName = "MSFT";
		int numberOfShares = 200;
		log("Selling " + numberOfShares + " of " + stockName);
		TradeResult tr = trader.sell(customerName, stockName, numberOfShares);
		log(tr.toString());

		// Buy some stock
		stockName = "BEAS";
		numberOfShares = 250;
		log("Buying " + numberOfShares + " of " + stockName);
		tr = trader.buy(customerName, stockName, numberOfShares);
		log(tr.toString());

		// Get change in Cash Account from EJBean
		log("Change in Cash Account: $" + trader.getBalance() + "\n");

		log("Local Ejb test start...");

		log("testing localTrader balance is:" + trader.testLocal());

		log("Local Ejb test end...");
		log("Removing trader\n");
		trader.remove();

	}

	/**
	 * RMI/IIOP clients should use this narrow function
	 */
	private Object narrow(Object ref, Class c) {
		return PortableRemoteObject.narrow(ref, c);
	}

	/**
	 * Lookup the EJBs home in the JNDI tree
	 */
	private TraderHome lookupHome() throws NamingException {
		// Lookup the beans home using JNDI
		Context ctx = getInitialContext();
		try {
			Object home = ctx.lookup(JNDI_NAME);
			return (TraderHome) narrow(home, TraderHome.class);
		} 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 "
					+ JNDI_NAME + " on the WebLogic server at " + url);
			throw ne;
		}
	}

	/**
	 * Using a Properties object will work on JDK 1.1.x and Java2 clients
	 */
	private Context getInitialContext() throws NamingException {
		try {
			// Get an InitialContext
			Hashtable<String, String> h = new Hashtable<String, String>();
			h.put(Context.INITIAL_CONTEXT_FACTORY,
					"weblogic.jndi.WLInitialContextFactory");
			h.put(Context.PROVIDER_URL, url);
			return new InitialContext(h);
		} catch (NamingException ne) {
			log("We were unable to get a connection to the WebLogic server at "
					+ url);
			log("Please make sure that the server is running.");
			throw ne;
		}
	}

	private static void log(String s) {
		System.out.println(s);
	}

}

 

9.ejb-jar.xml

<ejb-jar>
	<enterprise-beans>
		<session>
			<ejb-name>TraderEJB</ejb-name>
			<home>ejb.stateful.TraderHome</home>
			<remote>ejb.stateful.Trader</remote>
			<local-home>ejb.stateful.TraderLocalHome</local-home>
			<local>ejb.stateful.TraderLocal</local>
			<ejb-class>ejb.stateful.TraderBean</ejb-class>
			<session-type>Stateful</session-type>
			<transaction-type>Container</transaction-type>
			<env-entry>
				<env-entry-name>BEAS</env-entry-name>
				<env-entry-type>java.lang.Double</env-entry-type>
				<env-entry-value>100.00</env-entry-value>
			</env-entry>
			<env-entry>
				<env-entry-name>MSFT</env-entry-name>
				<env-entry-type>java.lang.Double</env-entry-type>
				<env-entry-value>150.00</env-entry-value>
			</env-entry>
		</session>
	</enterprise-beans>
	<assembly-descriptor>
		<container-transaction>
			<method>
				<ejb-name>TraderEJB</ejb-name>
				<method-name>*</method-name>
			</method>
			<trans-attribute>Required</trans-attribute>
		</container-transaction>
	</assembly-descriptor>
</ejb-jar>

 

10.weblogic-ejb-jar.xml

<weblogic-ejb-jar>
	<weblogic-enterprise-bean>
		<ejb-name>TraderEJB</ejb-name>
		<stateful-session-descriptor/>
		<jndi-name>ejb20-statefulSession-TraderHome</jndi-name>
		<local-jndi-name>ejb/TraderEJB</local-jndi-name>
	</weblogic-enterprise-bean>
</weblogic-ejb-jar>

 

11.run Client.java测试结果

Beginning statefulSession.Client...

Creating trader

Selling 200 of MSFT
200 sharessold at a price of 150.0
Buying 250 of BEAS
250 sharesbought at a price of 100.0
Change in Cash Account: $5000.0

Local Ejb test start...
testing localTrader balance is:0.0
Local Ejb test end...
Removing trader


End statefulSession.Client...

 

你可能感兴趣的:(bean,xml,weblogic,ejb,UP)