Võ Văn Hải's blog

Chỉ có một điều tuyệt đối đó là mọi thứ đều tương đối…

STATEFULL SESSION BEAN – EJB3 VÀ 1 VÍ DỤ VỀ SHOPPINGCART

PDF version here

I. Thiết lập môi trường

Thiết lập classpath của bạn đầy đủ đến các thư viện jar của ejb3. Ở đây tôi thiết lập các tham số sau cho classpath:

%JBOSS_HOME%client\jboss-j2ee.jar;%JBOSS_HOME%client\jnp-client.jar; %JBOSS_HOME%client\jboss-common-client.jar; %JBOSS_HOME%client\concurrent.jar;%JBOSS_HOME%client\jboss-client.jar; %JBOSS_HOME%client\jboss-serialization.jar; %JBOSS_HOME%client\jboss-remoting.jar; %JBOSS_HOME%client\jbosssx-client.jar; %JBOSS_HOME%client\jboss-transaction-client.jar;% JBOSS_HOME%client\jbossall-client.jar; %JBOSS_HOME%\mail.jar; %JBOSS_HOME%\client\jboss-ejb3x.jar;

II. Cài đặt

1. Tạo thư mục ShoppingCart_EJB3. Tất cả bài demo được lưu ở đây.

2. Tạo thư mục server, các lớp viết cho triển khai ejb nằm ở đây

3. Tạo file Item.java để đặt tả cho 1 món hàng có nội dung sau

package shopping;

import java.io.Serializable;

public class Item implements Serializable{

private static final long serialVersionUID = 1L;

private String name;

private double price;

public Item() {

super();

}

public Item(String name, double price) {

super();

this.name = name;

this.price = price;

}

public String getName() {

return name;

}

public void setName(String name) {

this.name = name;

}

public double getPrice() {

return price;

}

public void setPrice(double price) {

this.price = price;

}

}

4. Tạo file ShoppingCartRemote.java có nội dung sau

package shopping;

import java.util.ArrayList;

import javax.ejb.Remote;

@Remote

public interface ShoppingCartRemote {

public double getTotalAmount();

public void addToCart(Item item);

public ArrayList<Item>getCart();

}

5. Tạo file ShoppingCart.java có nội dung sau

package shopping;

import java.util.ArrayList;

import javax.ejb.Stateful;

@Stateful

public class ShoppingCart implements ShoppingCartRemote {

private ArrayList<Item>cart;

public ShoppingCart(){

cart=new ArrayList<Item>();

}

@Override

public void addToCart(Item item) {

cart.add(item);

}

@Override

public ArrayList<Item> getCart() {

return cart;

}

@Override

public double getTotalAmount() {

double total=0;

if(cart==null||cart.size()==0)

return total;

for(Item it:cart)

total+=it.getPrice();

return total;

}

}

6. Tạo thư mục META-INF, sau đó tạo file jboss.xml trong thư mục này có nội dung như sau :

<?xml version=1.0 encoding=UTF-8?>

<!DOCTYPE jboss PUBLIC -//JBoss//DTD JBOSS 4.0//EN http://www.jboss.org/j2ee/dtd/jboss_4_0.dtd>

<jboss>

<enterprise-beans>

<session>

<ejb-name>ShoppingCart</ejb-name>

<jndi-name>ShoppingCartEJB3</jndi-name>

</session>

</enterprise-beans>

</jboss>

III. Đóng gói và Triển Khai

1. Tạo file compile.bat có nội dung sau

javac -d . *.java

pause

Đảm bảo việc compile không có lỗi.

2. Tạo file createJAR.bat để tạo file jar có nội dung sau:

jar cvf EJB3_Statfull_ShoppingCart.jar shopping/*.class META-INF/*.xml

pause

Tạo file EJB3_Statfull_ShoppingCart.jar bằng cách chạy file này.

3. Triển khai

Copy file EJB3_Statfull_ShoppingCart.jar vào thư mục %JBOSS_HOME%\server\default\deploy\

Kết quả ta có như sau :

14:23:31,810 INFO [JmxKernelAbstraction] creating wrapper delegate for: org.jboss.ejb3.stateful.StatefulContainer

14:23:31,815 INFO [JmxKernelAbstraction] installing MBean: jboss.j2ee:jar=EJB3_Statfull_ShoppingCart.jar,name=ShoppingCart,service=EJB3 with dependencies:

14:23:31,851 INFO [EJBContainer] STARTED EJB: shopping.ShoppingCart ejbName: ShoppingCart

14:23:31,897 INFO [EJB3Deployer] Deployed: file:/C:/javaSoft/jboss-4.2.2.GA/server/default/deploy/EJB3_Statfull_ShoppingCart.jar

IV. Client application

1. Tạo thư mục client sau đó copy thư mục shopping vào đấy

2. Tạo tập tin EJB3_Statfull_ShoppingCart_Client.java có nội dung sau

package vovanhai.wordpress.com;

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Font;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.ArrayList;

import javax.naming.InitialContext;
import javax.swing.BorderFactory;
import javax.swing.Box;
import javax.swing.JButton;
import javax.swing.JComboBox;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.JTextField;
import javax.swing.table.DefaultTableModel;

import shopping.*;

public class EJB3_Statfull_ShoppingCart_Client extends JFrame implements ActionListener{
private DefaultTableModel dtm;
private JTable table;
private JComboBox cboProducts;
private JTextField tfPrice;
private JButton btAdd,btRem,btExit;
private JLabel lblSum;

ShoppingCartRemote cart;

public EJB3_Statfull_ShoppingCart_Client(){
setTitle(“My Shopping Cart”);
setSize(420,340);setResizable(false);
setDefaultCloseOperation(EXIT_ON_CLOSE);
JPanel pTop=new JPanel(new BorderLayout());
JPanel pCen=new JPanel(new BorderLayout());
pCen.setBorder(BorderFactory.createTitledBorder(“My Shopping Cart Listing”));
String []title={“Product Name”,”Price”};
table=new JTable(dtm=new DefaultTableModel(title,0));
pCen.add(new JScrollPane(table));
this.add(pCen,BorderLayout.CENTER);

JLabel l1,l2;
Box b=Box.createVerticalBox();Box b1=Box.createHorizontalBox();
Box b2=Box.createHorizontalBox();Box b3=Box.createHorizontalBox();
b1.add(l1=new JLabel(“Product Name:”,JLabel.RIGHT));
b1.add(cboProducts=new JComboBox());
b2.add(l2=new JLabel(“Price:”,JLabel.RIGHT));
b2.add(tfPrice=new JTextField(20));
l2.setPreferredSize(l1.getPreferredSize());b.add(Box.createVerticalStrut(8));
b.add(b1);b.add(Box.createVerticalStrut(8));
b.add(b2);b.add(Box.createVerticalStrut(8));
b.add(b3);b.add(Box.createVerticalStrut(8));

b3.add(btAdd=new JButton(“Add Item”));btAdd.addActionListener(this);
b3.add(btRem=new JButton(“Remove Item”));btRem.addActionListener(this);
b3.add(btExit=new JButton(“Exit”));btExit.addActionListener(this);

this.add(pTop,BorderLayout.NORTH);
pTop.add(b,BorderLayout.CENTER);
JLabel lTitle=new JLabel(“SHOPPING CART”,JLabel.CENTER);
lTitle.setFont(new Font(“Arial”,Font.BOLD,20));
lTitle.setForeground(Color.blue);
pTop.add(lTitle,BorderLayout.NORTH);

JPanel pBot=new JPanel();
pBot.add(new JLabel(“Tổng tiền:”));
pBot.add(lblSum=new JLabel());lblSum.setForeground(Color.red);
this.add(pBot,BorderLayout.SOUTH);

generateSampleData();
Ref2EJB();
}
void generateSampleData(){
cboProducts.addItem(“Xoài”);
cboProducts.addItem(“Cóc”);
cboProducts.addItem(“Ổi”);
cboProducts.addItem(“Mận”);
cboProducts.addItem(“Mít”);
cboProducts.addItem(“Me dốt”);
cboProducts.addItem(“Ô mai”);
}
void Ref2EJB(){
try {
System.setProperty( “java.naming.factory.initial”, “org.jnp.interfaces.NamingContextFactory” );
System.setProperty( “java.naming.provider.url”, “localhost:1099” );
System.setProperty( “java.naming.factory.url.pkgs”, “org.jboss.naming” );

InitialContext ctx=new InitialContext();
Object obj = ctx.lookup(“ShoppingCartEJB3”);

cart=(ShoppingCartRemote)javax.rmi.PortableRemoteObject.narrow(obj, ShoppingCartRemote.class);
} catch ( Exception ex ) {
ex.printStackTrace();
}
}
void BuildProductsList(){
double sum=0;
dtm.setRowCount(0);
ArrayList<Item> ds=cart.getCart();
for(Item item:ds){
String[]row={item.getName(),””+item.getPrice()};
dtm.addRow(row);
sum+=item.getPrice();
}
lblSum.setText(“”+sum);
}
@Override
public void actionPerformed(ActionEvent e) {
Object o=e.getSource();
if(o.equals(btExit))
System.exit(1);
if(o.equals(btAdd)){
double price=0;
try {
price=Double.parseDouble(tfPrice.getText());
} catch (Exception e2) {
JOptionPane.showMessageDialog(null, “Làm ơn Nhập số”);
return;
}
Item it=new Item(cboProducts.getSelectedItem().toString(),price);
cart.addToCart(it);
BuildProductsList();
}
else if(o.equals(btRem)){
cart.RemoveFromCart(cboProducts.getSelectedItem().toString());
BuildProductsList();
}
}

public static void main(String[] args) {
new EJB3_Statfull_ShoppingCart_Client().setVisible(true);
}
}

3. Tạo file compile.bat có nội dung sau

javac -d . *.java

pause

Chạy file này và đảm bảo không có lỗi nào

4. Tạo file run.bat có nội dung sau

java vovanhai/wordpress/com/MyCart
pause

5. Thực thi file run.bat, kết quả ta được như sau

https://vovanhai.files.wordpress.com/2008/10/ejb3shoppingcart1.png

CHÚC CÁC BẠN THÀNH CÔNG!

10 Responses to “STATEFULL SESSION BEAN – EJB3 VÀ 1 VÍ DỤ VỀ SHOPPINGCART”

  1. Kaka said

    Chào anh, cho phép em hỏi 1 vấn đề:
    Trong Bean (file ShoppingCart.java), nếu em thêm 1 hàm constructor có tham số, ví dụ như CustName kiểu String, thì bên phía Client mình phải lookup như thế nào thì Bean của mình mới chạy hàm constructor có tham số đó.
    Mong anh hồi âm cho vấn đề của em, thanks.

  2. trung said

    cho em hỏi là nếu mình chuyển stateful thành stateless thì chuyện gì sẽ xảy ra? nó có ảnh hưởng như thế nào cho ứng dụng trên? em cũng đọc qua 2 cái session đó but không hiểu rõ mấy, mong thầy giúp đỡ

  3. Phuc said

    Chào anh,
    Hình như trong inteface ShoppingCartRemote khong co hàm RemoveFromCart(String ), chính vì vậy khi compile file EJB3_Statfull_ShoppingCart_Client.java có báo lỗi ở đoạn
    cart.RemoveFromCart(cboProducts.getSelectedItem().toString());
    Mong anh xem lại.
    Cám ơn.

  4. Võ Văn Hải said

    Nếu chưa có thì bạn có thể thêm vào mà! Thanks!

  5. duykhanh said

    em chào thầy!
    em có thắc mắc là:
    1. @Stateful và @SessionScoped (Managed Bean) có khác nhau gì không? Và khi nào thì mình sẽ dùng nó ?
    2. Em khai báo @Stateful cho 1 class nhưng khi dùng thì class này không lưu trạng thái ?

  6. duykhanh said

    http://seamframework.org/Community/DifferenceBetweenStatefulAndSESSIONScope
    Em có vào trang này đọc nhưng không hiểu lắm, mong thầy chỉ giúp. em cảm ơn thầy!

  7. Võ Văn Hải said

    1. @Stateful để báo bean ở đây là Stafulul Session Bean. Còn @SessionScope là phạm vi (scope) của managedbean(tức là biến này được lưu ở mức session).
    2. Em dùng như thế nào thì thầy không rõ nên không trả lời được. Còn stateful session bean thì có lưu trạng thái.

  8. duykhanh said

    ah quên, thầy có tài liệu Core JavaServer Faces tiếng việt không thầy? em cảm ơn thầy nhiều!

  9. Pham Thanh Thuan said

    mình có class ScurityUtil.java (http://www.mediafire.com/?twnp0s2lwdzear6) các bro tải về dùng thử xem có lỗi ko cho mình ý kiến.
    Trong thư viện này có nhiều hàm nhưng mình chỉ dùng 2 hàm:

    +Hàm mã hóa dữ liệu:

    public static String encrypt(String data, String password)
    {
    return Base64Encoder.encode(encrypt(data.getByte(),passwo rd));
    }
    hàm này sử dụng thành công.

    + Hàm giải mã giữ liệu đã mã hóa:

    public static String decrypt(String data, String password)
    {
    return decrypt(Base64Decoder.decode.getByte(data),passwor d);
    }

    khi sử dụng hàm này thì báo lỗi java.lang.ArrayIndexOutOfBoundsException: 209.

    Mong các bro dành chút thời gian test dùm thư viện này và cho ý kiến thank các bro rất nhiều!!!

  10. Pham Thanh Thuan said

    xin hỏi thêm cách khai báo một mãng session trong EJB 3.0

    ví dụ:
    ở đây mình có 1 class JSF.java dùng để gọi những parameter ngoài JSF 2.0 và goi các Session vào các class controler, chủ yếu class JSF.java là khi dùng nó thì Session và nhiều thứ khác không cần phải khởi tạo lại.

    gán một thuộc tính vào session:

    JFS.getSession().setAttribute(“ten session”, entity.getIdMember);

    khai báo một mảng thường:

    String [] thunghiem = JSF.getRequest.getParameterValues(“tên parameter”);

    vậy muốn mảng thunghiem thành 1 mảng Session thì viết như thế nào xin mọi người chỉ giúp.
    cám ơn rất nhiều!!!!

Leave a comment

This site uses Akismet to reduce spam. Learn how your comment data is processed.