EJB - คู่มือฉบับย่อ

EJB ย่อมาจาก Enterprise Java Beans. EJB เป็นส่วนสำคัญของแพลตฟอร์ม J2EE แพลตฟอร์ม J2EE มีสถาปัตยกรรมตามส่วนประกอบเพื่อให้คุณสมบัติหลายชั้นกระจายและมีธุรกรรมสูงสำหรับแอปพลิเคชันระดับองค์กร

EJB จัดเตรียมสถาปัตยกรรมเพื่อพัฒนาและปรับใช้แอปพลิเคชันระดับองค์กรโดยพิจารณาจากความทนทานความสามารถในการปรับขนาดได้สูงและประสิทธิภาพสูง แอปพลิเคชัน EJB สามารถปรับใช้กับแอ็พพลิเคชันเซิร์ฟเวอร์ใดก็ได้ที่เป็นไปตามข้อกำหนดมาตรฐาน J2EE 1.3

เราจะพูดถึงรายละเอียด EJB 3.0 ในบทช่วยสอนนี้

ประเภท

EJB แบ่งออกเป็นสามประเภทหลัก ๆ ตารางต่อไปนี้แสดงรายชื่อพร้อมคำอธิบายสั้น ๆ -

ส. เลขที่ ประเภทและคำอธิบาย
1

Session Bean

Session bean เก็บข้อมูลของผู้ใช้เฉพาะสำหรับเซสชันเดียว มันสามารถstateful หรือ stateless. ใช้ทรัพยากรน้อยกว่าเมื่อเทียบกับเอนทิตีบีน Session bean ถูกทำลายทันทีที่เซสชันของผู้ใช้สิ้นสุดลง

2

Entity Bean

Entity beansแสดงถึงการจัดเก็บข้อมูลแบบถาวร ข้อมูลผู้ใช้สามารถบันทึกลงในฐานข้อมูลผ่านทางเอนทิตีบีนและในภายหลังสามารถดึงมาจากฐานข้อมูลในเอนทิตีบีน

3

Message Driven Bean

Message driven beansใช้ในบริบทของ JMS (Java Messaging Service) Message Driven Beans สามารถใช้ข้อความ JMS จากเอนทิตีภายนอกและดำเนินการตามนั้น

สิทธิประโยชน์

ต่อไปนี้เป็นประโยชน์ที่สำคัญของ EJB -

  • การพัฒนาแอปพลิเคชันระดับองค์กรขนาดใหญ่ที่ง่ายขึ้น

  • Application Server / EJB container ให้บริการระดับระบบส่วนใหญ่เช่นการจัดการธุรกรรมการบันทึกการทำโหลดบาลานซ์กลไกการคงอยู่การจัดการข้อยกเว้นและอื่น ๆ นักพัฒนาต้องมุ่งเน้นเฉพาะตรรกะทางธุรกิจของแอปพลิเคชัน

  • คอนเทนเนอร์ EJB จัดการวงจรชีวิตของอินสแตนซ์ EJB ดังนั้นนักพัฒนาจึงไม่ต้องกังวลว่าจะสร้าง / ลบออบเจ็กต์ EJB เมื่อใด

EJB เป็นเฟรมเวิร์กสำหรับ Java ดังนั้นข้อกำหนดแรกสุดคือต้องมีไฟล์ Java Dการพัฒนา Kติดตั้ง (JDK) ในเครื่องของคุณ

ความต้องการของระบบ

JDK 1.5 ขึ้นไป
หน่วยความจำ ไม่มีข้อกำหนดขั้นต่ำ
พื้นที่ดิสก์ ไม่มีข้อกำหนดขั้นต่ำ
ระบบปฏิบัติการ ไม่มีข้อกำหนดขั้นต่ำ

ขั้นตอนที่ 1 - ตรวจสอบการติดตั้ง Java ในระบบของคุณ

ตอนนี้เปิดคอนโซลและดำเนินการต่อไปนี้ java คำสั่ง

ระบบปฏิบัติการ งาน คำสั่ง
Windows เปิด Command Console c: \> java - เวอร์ชัน
ลินุกซ์ เปิด Command Terminal $ java - รุ่น
Mac เปิด Terminal เครื่อง: ~ joseph $ java -version

มาตรวจสอบผลลัพธ์สำหรับระบบปฏิบัติการทั้งหมด -

ระบบปฏิบัติการ เอาต์พุต
Windows

เวอร์ชัน java "1.6.0_21"

สภาพแวดล้อมรันไทม์ Java (TM) SE (สร้าง 1.6.0_21-b11)

Java HotSpot (TM) 64-Bit Server VM (สร้าง 23.21-b01, โหมดผสม)

ลินุกซ์

เวอร์ชัน java "1.6.0_21"

สภาพแวดล้อมรันไทม์ Java (TM) SE (สร้าง 1.6.0_21-b11)

Java HotSpot (TM) 64-Bit Server VM (สร้าง 23.21-b01, โหมดผสม)

Mac

เวอร์ชัน java "1.6.0_21"

สภาพแวดล้อมรันไทม์ Java (TM) SE (สร้าง 1.6.0_21-b11)

Java HotSpot (TM) 64-Bit Server VM (สร้าง 23.21-b01, โหมดผสม)

หากคุณไม่ได้มีการติดตั้ง Java ติดตั้ง Java Software Development Kit (SDK) จากwww.oracle.com เราสมมติว่า Java 1.6.0_21 เป็นเวอร์ชันที่ติดตั้งสำหรับบทช่วยสอนนี้

ขั้นตอนที่ 2 - ตั้งค่าสภาพแวดล้อม JAVA

ตั้งค่า JAVA_HOMEตัวแปรสภาพแวดล้อมเพื่อชี้ตำแหน่งไดเร็กทอรีฐานที่ติดตั้ง Java บนระบบของคุณ ตัวอย่างเช่น,

ระบบปฏิบัติการ เอาต์พุต
Windows ตั้งค่าตัวแปรสภาพแวดล้อม JAVA_HOME เป็น C: \ Program Files \ Java \ jdk1.6.0_21
ลินุกซ์ ส่งออก JAVA_HOME = / usr / local / java-current
Mac ส่งออก JAVA_HOME = / Library / Java / Home

ผนวกตำแหน่งคอมไพเลอร์ Java เข้ากับ System Path

ระบบปฏิบัติการ เอาต์พุต
Windows ต่อท้ายสตริง C: \ Program Files \ Java \ jdk1.6.0_21 \ bin ต่อท้ายตัวแปรระบบ Path
ลินุกซ์ ส่งออก PATH =$PATH:$JAVA_HOME / bin /
Mac ไม่จำเป็นต้องใช้

ตรวจสอบการติดตั้ง Java โดยใช้ java -version คำสั่งที่อธิบายไว้ข้างต้น

ขั้นตอนที่ 3 - ดาวน์โหลดและติดตั้ง NetBeans IDE

ดาวน์โหลดรุ่นล่าสุดของ NetBeans IDE จากnetbeans.org ในขณะที่เขียนบทช่วยสอนนี้ฉันดาวน์โหลดNetbeans 7.3ซึ่งมาพร้อมกับ JDK 1.7 โดยใช้ลิงค์ต่อไปนี้www.oracle.com

ระบบปฏิบัติการ ชื่อผู้ติดตั้ง
Windows Netbeans 7.3
ลินุกซ์ Netbeans 7.3
Mac Netbeans 7.3

ขั้นตอนที่ 4 - ตั้งค่าเซิร์ฟเวอร์แอปพลิเคชัน JBoss

คุณสามารถดาวน์โหลดรุ่นล่าสุดของ JBoss Server จากwww.jboss.org ดาวน์โหลดไฟล์เก็บถาวรตามแพลตฟอร์ม แยก Jboss ไปยังตำแหน่งใดก็ได้บนเครื่องของคุณ

ระบบปฏิบัติการ ชื่อไฟล์
Windows jboss-5.1.0.GA-jdk6.zip
ลินุกซ์ jboss-5.1.0.GA-src.tar.gz
Mac jboss-5.1.0.GA-src.tar.gz

ขั้นตอนที่ 5 - กำหนดค่าปลั๊กอิน JEE เป็น Netbeans

เปิดหน้าต่างปลั๊กอินโดยใช้เครื่องมือ> ปลั๊กอิน เปิดแท็บ "ปลั๊กอินที่พร้อมใช้งาน" และเลือก "Java EE Base" และ "EJB and EAR" ภายใต้หมวดหมู่ "Java Web and EE" คลิกปุ่มติดตั้ง Netbeans จะดาวน์โหลดและติดตั้งปลั๊กอินที่เกี่ยวข้อง ตรวจสอบการติดตั้งปลั๊กอินโดยใช้แท็บ "ติดตั้งแล้ว" (ดังแสดงในภาพด้านล่าง)

ขั้นตอนที่ 6 - กำหนดค่าเซิร์ฟเวอร์ JBoss ใน Netbeans

ไปที่แท็บบริการและคลิกขวาที่เซิร์ฟเวอร์เพื่อเพิ่มเซิร์ฟเวอร์ใหม่

เพิ่มตัวช่วยสร้างอินสแตนซ์เซิร์ฟเวอร์จะเปิดขึ้น เลือก JBoss และในขั้นตอนถัดไปให้ป้อนรายละเอียดที่เกี่ยวข้องเพื่อกำหนดค่าเซิร์ฟเวอร์ใน netbeans

เมื่อกำหนดค่าทุกอย่างแล้วคุณจะเห็นหน้าจอต่อไปนี้

ขั้นตอนที่ 7 - ติดตั้งเซิร์ฟเวอร์ฐานข้อมูล (PostGreSql)

ดาวน์โหลดรุ่นล่าสุดของเซิร์ฟเวอร์ฐานข้อมูล PostgreSQL จากwww.postgresql.org ในขณะที่เขียนบทช่วยสอนนี้ฉันดาวน์โหลดPostGreSql 9.2

ระบบปฏิบัติการ ชื่อผู้ติดตั้ง
Windows PostGreSql 9.2.2
ลินุกซ์ PostGreSql 9.2.2
Mac PostGreSql 9.2.2

ในการสร้างโมดูล EJB อย่างง่ายเราจะใช้ NetBeans ตัวช่วยสร้าง "โครงการใหม่" ในตัวอย่างด้านล่างเราจะสร้างโครงการโมดูล EJB ชื่อ Component

สร้างโครงการ

ใน NetBeans IDE เลือก File > New Project >. คุณจะเห็นหน้าจอต่อไปนี้

เลือกประเภทโครงการภายใต้หมวดหมู่ Java EE, ประเภทโครงการเป็น EJB Module. คลิกNext >ปุ่ม. คุณจะเห็นหน้าจอต่อไปนี้

ป้อนชื่อโครงการและที่ตั้ง คลิกNext >ปุ่ม. คุณจะเห็นหน้าจอต่อไปนี้

เลือกเซิร์ฟเวอร์เป็น JBoss Application Server. คลิกFinishปุ่ม. คุณจะเห็นโครงการต่อไปนี้ที่สร้างโดย NetBeans

สร้าง EJB ตัวอย่าง

ในการสร้าง EJB อย่างง่ายเราจะใช้ตัวช่วยสร้าง "ใหม่" ของ NetBeans ในตัวอย่างด้านล่างเราจะสร้างคลาส EJB ไร้สัญชาติชื่อ librarySessionBean ภายใต้โครงการ EjbComponent

เลือกโครงการ EjbComponent ในหน้าต่าง project explorer และคลิกขวาที่มัน เลือก,New > Session Bean. คุณจะเห็นไฟล์New Session Bean ตัวช่วย

ป้อนชื่อเซสชันบีนและชื่อแพ็กเกจ คลิกFinishปุ่ม. คุณจะเห็นคลาส EJB ต่อไปนี้ที่สร้างโดย NetBeans

  • LibrarySessionBean - ถั่วเซสชั่นไร้สัญชาติ

  • LibrarySessionBeanLocal - อินเทอร์เฟซท้องถิ่นสำหรับถั่วเซสชั่น

ฉันกำลังเปลี่ยนอินเทอร์เฟซภายในเป็นอินเทอร์เฟซระยะไกลเนื่องจากเรากำลังจะเข้าถึง EJB ของเราในแอปพลิเคชันที่ใช้คอนโซล อินเทอร์เฟซระยะไกล / โลคัลใช้เพื่อแสดงวิธีการทางธุรกิจที่ EJB ต้องนำไปใช้

LibrarySessionBeanLocal ถูกเปลี่ยนชื่อเป็น LibrarySessionBeanRemote และ LibrarySessionBean ใช้อินเตอร์เฟส LibrarySessionBeanRemote

LibrarySessionBeanRemote

package com.tutorialspoint.stateless;
 
import java.util.List;
import javax.ejb.Remote;
 
@Remote
public interface LibrarySessionBeanRemote {
   void addBook(String bookName);
   List getBooks();
}

ห้องสมุดเซสชันถั่ว

package com.tutorialspoint.stateless;
 
import java.util.ArrayList;
import java.util.List;
import javax.ejb.Stateless;
 
@Stateless
public class LibrarySessionBean implements LibrarySessionBeanRemote {
   
   List<String> bookShelf;    
   
   public LibrarySessionBean() {
      bookShelf = new ArrayList<String>();
   }
    
   public void addBook(String bookName) {
      bookShelf.add(bookName);
   }    
 
   public List<String> getBooks() {
      return bookShelf;
   }
}

สร้างโครงการ

  • เลือกโครงการ EjbComponent ในหน้าต่าง Project Explorer
  • คลิกขวาเพื่อเปิดเมนูบริบท
  • เลือกทำความสะอาดและสร้าง

คุณจะเห็นผลลัพธ์ต่อไปนี้ในเอาต์พุตคอนโซล NetBeans

ant -f C:\\EJB\\EjbComponent clean dist
init:
undeploy-clean:
deps-clean:
Deleting directory C:\EJB\EjbComponent\build
Deleting directory C:\EJB\EjbComponent\dist
clean:
init:
deps-jar:
Created dir: C:\EJB\EjbComponent\build\classes
Copying 3 files to C:\EJB\EjbComponent\build\classes\META-INF
Created dir: C:\EJB\EjbComponent\build\empty
Created dir: C:\EJB\EjbComponent\build\generated-sources\ap-source-output
Compiling 2 source files to C:\EJB\EjbComponent\build\classes
warning: [options] bootstrap class path not set in conjunction with -source 1.6
Note: C:\EJB\EjbComponent\src\java\com\tutorialspoint\stateless
\LibraryPersistentBean.java uses unchecked or unsafe operations.
Note: Recompile with -Xlint:unchecked for details.
1 warning
compile:
library-inclusion-in-archive:
Created dir: C:\EJB\EjbComponent\dist
Building jar: C:\EJB\EjbComponent\dist\EjbComponent.jar
dist:
BUILD SUCCESSFUL (total time: 3 seconds)

เริ่ม Application Server

  • เลือกเซิร์ฟเวอร์แอ็พพลิเคชัน JBoss ภายใต้หน้าต่างเซิร์ฟเวอร์ในบริการ
  • คลิกขวาเพื่อเปิดเมนูบริบท
  • เลือกเริ่มต้น

คุณจะเห็นผลลัพธ์ต่อไปนี้ใน NetBeans ผลลัพธ์ภายใต้ JBoss Application Server

Calling C:\jboss-5.1.0.GA\bin\run.conf.bat
=========================================================================
 
   JBoss Bootstrap Environment
 
   JBOSS_HOME: C:\jboss-5.1.0.GA
 
   JAVA: C:\Program Files (x86)\Java\jdk1.6.0_21\bin\java
 
   JAVA_OPTS: -Dprogram.name=run.bat -Xms128m -Xmx512m -server
 
   CLASSPATH: C:\jboss-5.1.0.GA\bin\run.jar
 
=========================================================================
 
16:25:50,062 INFO  [ServerImpl] Starting JBoss (Microcontainer)...
16:25:50,062 INFO  [ServerImpl] Release ID: JBoss 
   [The Oracle] 5.1.0.GA (build: SVNTag=JBoss_5_1_0_GA date=200905221634)
...
 
16:26:40,420 INFO  [TomcatDeployment] deploy, ctxPath=/admin-console
16:26:40,485 INFO  [config] Initializing Mojarra (1.2_12-b01-FCS) for context '/admin-console'
16:26:42,362 INFO  [TomcatDeployment] deploy, ctxPath=/
16:26:42,406 INFO  [TomcatDeployment] deploy, ctxPath=/jmx-console
16:26:42,471 INFO  [Http11Protocol] Starting Coyote HTTP/1.1 on http-127.0.0.1-8080
16:26:42,487 INFO  [AjpProtocol] Starting Coyote AJP/1.3 on ajp-127.0.0.1-8009
16:26:42,493 INFO  [ServerImpl] JBoss (Microcontainer) 
   [5.1.0.GA (build: SVNTag=JBoss_5_1_0_GA date=200905221634)] Started in 52s:427ms

ปรับใช้โครงการ

  • เลือกโครงการ EjbComponent ในหน้าต่าง Project Explorer
  • คลิกขวาเพื่อเปิดเมนูบริบท
  • เลือกปรับใช้

คุณจะเห็นผลลัพธ์ต่อไปนี้ในเอาต์พุตคอนโซล NetBeans

ant -f C:\\EJB\\EjbComponent -DforceRedeploy=true -Ddirectory.deployment.supported=false -Dnb.wait.for.caches=true run
init:
deps-jar:
compile:
library-inclusion-in-archive:
Building jar: C:\EJB\EjbComponent\dist\EjbComponent.jar
dist-directory-deploy:
pre-run-deploy:
Checking data source definitions for missing JDBC drivers...
Distributing C:\EJB\EjbComponent\dist\EjbComponent.jar to [org.jboss.deployment.spi.LocalhostTarget@1e4f84ee]
Deploying C:\EJB\EjbComponent\dist\EjbComponent.jar
Application Deployed
Operation start started
Operation start completed
post-run-deploy:
run-deploy:
run:
BUILD SUCCESSFUL (total time: 2 seconds)

เอาต์พุตบันทึกของเซิร์ฟเวอร์แอปพลิเคชัน JBoss

16:30:00,963 INFO  [DeployHandler] Begin start, [EjbComponent.jar]
...
16:30:01,233 INFO  [Ejb3DependenciesDeployer] Encountered deployment AbstractVFSDeploymentContext@12038795{vfszip:/C:/jboss-5.1.0.GA/server/default/deploy/EjbComponent.jar/}
...
16:30:01,281 INFO  [JBossASKernel]    jndi:LibrarySessionBean/remote-com.tutorialspoint.stateless.LibrarySessionBeanRemote
16:30:01,281 INFO  [JBossASKernel]    Class:com.tutorialspoint.stateless.LibrarySessionBeanRemote
16:30:01,281 INFO  [JBossASKernel]    jndi:LibrarySessionBean/remote
16:30:01,281 INFO  [JBossASKernel]  Added bean(jboss.j2ee:jar=EjbComponent.jar,name=
LibrarySessionBean,service=EJB3) to KernelDeployment of: EjbComponent.jar
16:30:01,282 INFO  [JBossASKernel] installing bean: jboss.j2ee:jar=EjbComponent.jar,name=BookMessageHandler,service=EJB3
16:30:01,282 INFO  [JBossASKernel]   with dependencies:
16:30:01,282 INFO  [JBossASKernel]   and demands:
16:30:01,282 INFO  [JBossASKernel]    jboss.ejb:service=EJBTimerService
...
16:30:01,283 INFO  [EJB3EndpointDeployer] Deploy 
AbstractBeanMetaData@5497cb{name=jboss.j2ee:jar=EjbComponent.jar, 
name=LibrarySessionBean, service=EJB3_endpoint bean=org.jboss.ejb3.endpoint.deployers.impl.EndpointImpl properties=[container] constructor=null autowireCandidate=true}
...
16:30:01,394 INFO  [SessionSpecContainer] Starting jboss.j2ee:jar=EjbComponent.jar,name=LibrarySessionBean,service=EJB3
16:30:01,395 INFO  [EJBContainer] STARTED EJB: com.tutorialspoint.stateless.LibrarySessionBean ejbName: LibrarySessionBean
16:30:01,401 INFO  [JndiSessionRegistrarBase] Binding the following Entries in Global JNDI:
   LibrarySessionBean/remote - EJB3.x Default Remote Business Interface
   LibrarySessionBean/remote-com.tutorialspoint.stateless.LibrarySessionBeanRemote - EJB3.x Remote Business Interface
16:30:02,723 INFO  [SessionSpecContainer] Starting jboss.j2ee:jar=EjbComponent.jar,name=LibrarySessionBean,service=EJB3
16:30:02,723 INFO  [EJBContainer] STARTED EJB: com.tutorialspoint.stateless.LibrarySessionBean ejbName: LibrarySessionBean
16:30:02,731 INFO  [JndiSessionRegistrarBase] Binding the following Entries in Global JNDI:
 
   LibrarySessionBean/remote - EJB3.x Default Remote Business Interface
   LibrarySessionBean/remote-com.tutorialspoint.stateless.LibrarySessionBeanRemote - EJB3.x Remote Business Interface

สร้างไคลเอนต์เพื่อเข้าถึง EJB

  • ใน NetBeans IDE เลือก File > New Project >.

  • เลือกประเภทโครงการภายใต้หมวดหมู่ Java, ประเภทโครงการเป็น Java Application. คลิกปุ่มถัดไป>

  • ป้อนชื่อโครงการและที่ตั้ง คลิกFinish >ปุ่ม. เราได้เลือกชื่อเป็น EjbTester

  • คลิกขวาที่ชื่อโครงการในหน้าต่าง Project explorer เลือกproperties.

  • เพิ่มโครงการคอมโพเนนต์ EJB ที่สร้างขึ้นก่อนหน้านี้ภายใต้ไลบรารีโดยใช้ Add Project ปุ่มใน compile แท็บ

  • เพิ่มไลบรารี jboss โดยใช้ Add jar/folder ปุ่มใน compileแท็บ ไลบรารี Jboss สามารถอยู่ที่ <โฟลเดอร์การติดตั้ง jboss >> โฟลเดอร์ไคลเอ็นต์

สร้าง jndi.properties ภายใต้โครงการพูดว่า EjbTester

jndi.properties

java.naming.factory.initial=org.jnp.interfaces.NamingContextFactory
java.naming.factory.url.pkgs=org.jboss.naming:org.jnp.interfaces
java.naming.provider.url=localhost

สร้างแพ็กเกจ com.tutorialspoint.test และคลาส EJBTester.java ภายใต้มัน

EJBTester.java

package com.tutorialspoint.test;
 
import com.tutorialspoint.stateless.LibrarySessionBeanRemote;
import java.io.BufferedReader;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.List;
import java.util.Properties;
import javax.naming.InitialContext;
import javax.naming.NamingException;
 
 
public class EJBTester {
   BufferedReader brConsoleReader = null; 
   Properties props;
   InitialContext ctx;
   {
      props = new Properties();
      try {
         props.load(new FileInputStream("jndi.properties"));
      } catch (IOException ex) {
         ex.printStackTrace();
      }
      try {
         ctx = new InitialContext(props);            
      } catch (NamingException ex) {
         ex.printStackTrace();
      }
      brConsoleReader = 
      new BufferedReader(new InputStreamReader(System.in));
   }
   public static void main(String[] args) {
 
      EJBTester ejbTester = new EJBTester();
 
      ejbTester.testStatelessEjb();
   }
   private void showGUI() {
      System.out.println("**********************");
      System.out.println("Welcome to Book Store");
      System.out.println("**********************");
      System.out.print("Options \n1. Add Book\n2. Exit \nEnter Choice: ");
   }
   private void testStatelessEjb() {
      try {
         int choice = 1; 
         LibrarySessionBeanRemote libraryBean = 
         (LibrarySessionBeanRemote)ctx.lookup("LibrarySessionBean/remote");
         while (choice != 2) {
            String bookName;
            showGUI();
            String strChoice = brConsoleReader.readLine();
            choice = Integer.parseInt(strChoice);
            if (choice == 1) {
               System.out.print("Enter book name: ");
               bookName = brConsoleReader.readLine();                    
               libraryBean.addBook(bookName);          
            }else if (choice == 2) {
               break;
            }
         }
         List<String> booksList = libraryBean.getBooks();
         System.out.println("Book(s) entered so far: " + booksList.size());
         for (int i = 0; i < booksList.size(); ++i) {
            System.out.println((i+1)+". " + booksList.get(i));
         }
         LibrarySessionBeanRemote libraryBean1 = 
         (LibrarySessionBeanRemote)ctx.lookup("LibrarySessionBean/remote");
         List<String> booksList1 = libraryBean1.getBooks();
         System.out.println(
            "***Using second lookup to get library stateless object***");
         System.out.println(
            "Book(s) entered so far: " + booksList1.size());
         for (int i = 0; i < booksList1.size(); ++i) {
            System.out.println((i+1)+". " + booksList1.get(i));
         }
      } catch (Exception e) {
         System.out.println(e.getMessage());
         e.printStackTrace();
      } finally {
         try {
            if(brConsoleReader !=null) {
               brConsoleReader.close();
            }
         } catch (IOException ex) {
            System.out.println(ex.getMessage());
         }
      }
   }  
}

เรียกใช้ไคลเอ็นต์เพื่อเข้าถึง EJB

ค้นหา EJBTester.java ใน project explorer คลิกขวาที่คลาส EJBTester และเลือกrun file.

ตรวจสอบเอาต์พุตต่อไปนี้ในคอนโซล Netbeans

run:
**********************
Welcome to Book Store
**********************
Options 
1. Add Book
2. Exit 
Enter Choice: 1
Enter book name: Learn Java
**********************
Welcome to Book Store
**********************
Options 
1. Add Book
2. Exit 
Enter Choice: 2
Book(s) entered so far: 1
1. Learn Java
***Using second lookup to get library stateless object***
Book(s) entered so far: 0
BUILD SUCCESSFUL (total time: 13 seconds)

ในบทต่อไปนี้เราจะครอบคลุมหลาย ๆ ด้านของแอปพลิเคชัน EJB ที่สมบูรณ์นี้

เซสชั่นบีนไร้สัญชาติเป็นเอ็นเตอร์ไพรส์บีนประเภทหนึ่งซึ่งโดยปกติจะใช้เพื่อดำเนินการอย่างอิสระ เซสชันถั่วที่ไม่มีสถานะตามชื่อไม่มีสถานะไคลเอ็นต์ใด ๆ ที่เกี่ยวข้อง แต่อาจรักษาสถานะอินสแตนซ์ไว้ โดยปกติ EJB Container จะสร้างพูลของออบเจ็กต์ของถั่วไร้สถานะเพียงไม่กี่ตัวและใช้อ็อบเจ็กต์เหล่านี้เพื่อดำเนินการตามคำขอของไคลเอ็นต์ เนื่องจากพูลจึงไม่รับประกันว่าค่าตัวแปรอินสแตนซ์จะเหมือนกันในการเรียกค้นหา / วิธีการ

ขั้นตอนในการสร้าง EJB ไร้สัญชาติ

ต่อไปนี้เป็นขั้นตอนที่จำเป็นในการสร้าง EJB ไร้สัญชาติ -

  • สร้างอินเทอร์เฟซระยะไกล / โลคัลเพื่อเปิดเผยวิธีการทางธุรกิจ

  • อินเทอร์เฟซนี้จะถูกใช้โดยแอปพลิเคชันไคลเอนต์ EJB

  • ใช้คำอธิบายประกอบ @Local หากไคลเอ็นต์ EJB อยู่ในสภาพแวดล้อมเดียวกันกับที่จะปรับใช้เซสชันถั่ว EJB

  • ใช้คำอธิบายประกอบ @Remote หากไคลเอ็นต์ EJB อยู่ในสภาพแวดล้อมที่แตกต่างกันที่จะปรับใช้ EJB session bean

  • สร้างเซสชัน bean แบบไร้สถานะโดยใช้อินเทอร์เฟซด้านบน

  • ใช้คำอธิบายประกอบ @Stateless เพื่อแสดงว่าเป็นถั่วไร้สัญชาติ EJB Container จะสร้างคอนฟิกูเรชันหรืออินเทอร์เฟซที่เกี่ยวข้องโดยอัตโนมัติโดยอ่านคำอธิบายประกอบนี้ระหว่างการปรับใช้

อินเทอร์เฟซระยะไกล

import javax.ejb.Remote;
 
@Remote
public interface LibrarySessionBeanRemote {
   //add business method declarations
}

EJB ไร้สัญชาติ

@Stateless
public class LibrarySessionBean implements LibrarySessionBeanRemote {
   //implement business method 
}

ตัวอย่างการใช้งาน

ให้เราสร้างแอปพลิเคชันทดสอบ EJB เพื่อทดสอบ EJB ไร้สัญชาติ

ขั้นตอน คำอธิบาย
1

สร้างโครงการที่มีชื่อEjbComponentภายใต้แพคเกจcom.tutorialspoint.statelessตามที่อธิบายไว้ในEJB - สร้างแอพลิเคชันบท คุณยังสามารถใช้โปรเจ็กต์ที่สร้างในEJB - สร้างบทแอปพลิเคชันสำหรับบทนี้เพื่อทำความเข้าใจแนวคิด EJB แบบไร้สัญชาติ

2

สร้างLibrarySessionBean.javaและLibrarySessionBeanRemoteตามที่อธิบายไว้ในEJB - สร้างแอพลิเคชันบท เก็บไฟล์ที่เหลือไว้ไม่เปลี่ยนแปลง

3

ทำความสะอาดและสร้างแอปพลิเคชันเพื่อให้แน่ใจว่าตรรกะทางธุรกิจทำงานได้ตามข้อกำหนด

4

สุดท้ายปรับใช้แอปพลิเคชันในรูปแบบของไฟล์ jar บน JBoss Application Server เซิร์ฟเวอร์แอปพลิเคชัน JBoss จะเริ่มทำงานโดยอัตโนมัติหากยังไม่เริ่มทำงาน

5

ตอนนี้สร้างไคลเอนต์ EJB ซึ่งเป็นแอปพลิเคชันบนคอนโซลในลักษณะเดียวกับที่อธิบายไว้ในบทEJB - Create Applicationภายใต้หัวข้อCreate Client to access EJB.

ส่วนประกอบ EJBC (โมดูล EJB)

LibrarySessionBeanRemote.java

package com.tutorialspoint.stateless;
 
import java.util.List;
import javax.ejb.Remote;
 
@Remote
public interface LibrarySessionBeanRemote {
   void addBook(String bookName);
   List getBooks();
}

LibrarySessionBean.java

package com.tutorialspoint.stateless;
 
import java.util.ArrayList;
import java.util.List;
import javax.ejb.Stateless;
 
@Stateless
public class LibrarySessionBean implements LibrarySessionBeanRemote {
    
   List<String> bookShelf;    
 
   public LibrarySessionBean() {
      bookShelf = new ArrayList<String>();
   }
 
   public void addBook(String bookName) {
      bookShelf.add(bookName);
   }    
 
   public List<String> getBooks() {
      return bookShelf;
   }
}
  • ทันทีที่คุณปรับใช้โครงการ EjbComponent บน JBOSS ให้สังเกตบันทึก jboss

  • JBoss ได้สร้างรายการ JNDI สำหรับถั่วเซสชันของเราโดยอัตโนมัติ - LibrarySessionBean/remote.

  • เราจะใช้สตริงการค้นหานี้เพื่อรับวัตถุทางธุรกิจระยะไกลประเภท - com.tutorialspoint.stateless.LibrarySessionBeanRemote

เอาต์พุตบันทึกของเซิร์ฟเวอร์แอปพลิเคชัน JBoss

...
16:30:01,401 INFO  [JndiSessionRegistrarBase] Binding the following Entries in Global JNDI:
   LibrarySessionBean/remote - EJB3.x Default Remote Business Interface
   LibrarySessionBean/remote-com.tutorialspoint.stateless.LibrarySessionBeanRemote - EJB3.x Remote Business Interface
16:30:02,723 INFO  [SessionSpecContainer] Starting jboss.j2ee:jar=EjbComponent.jar,name=LibrarySessionBean,service=EJB3
16:30:02,723 INFO  [EJBContainer] STARTED EJB: com.tutorialspoint.stateless.LibrarySessionBeanRemote ejbName: LibrarySessionBean
16:30:02,731 INFO  [JndiSessionRegistrarBase] Binding the following Entries in Global JNDI:
 
   LibrarySessionBean/remote - EJB3.x Default Remote Business Interface
   LibrarySessionBean/remote-com.tutorialspoint.stateless.LibrarySessionBeanRemote - EJB3.x Remote Business Interface
...

EJBTester (ไคลเอนต์ EJB)

jndi.properties

java.naming.factory.initial=org.jnp.interfaces.NamingContextFactory
java.naming.factory.url.pkgs=org.jboss.naming:org.jnp.interfaces
java.naming.provider.url=localhost
  • คุณสมบัติเหล่านี้ใช้เพื่อเริ่มต้นอ็อบเจ็กต์ InitialContext ของบริการการตั้งชื่อ java

  • วัตถุ InitialContext จะถูกใช้เพื่อค้นหาเซสชัน bean ที่ไม่มีสถานะ

EJBTester.java

package com.tutorialspoint.test;
   
import com.tutorialspoint.stateful.LibrarySessionBeanRemote;
import java.io.BufferedReader;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.List;
import java.util.Properties;
import javax.naming.InitialContext;
import javax.naming.NamingException;
 
public class EJBTester {
 
   BufferedReader brConsoleReader = null; 
   Properties props;
   InitialContext ctx;
   {
      props = new Properties();
      try {
         props.load(new FileInputStream("jndi.properties"));
      } catch (IOException ex) {
         ex.printStackTrace();
      }
      try {
         ctx = new InitialContext(props);            
      } catch (NamingException ex) {
         ex.printStackTrace();
      }
      brConsoleReader = 
      new BufferedReader(new InputStreamReader(System.in));
   }
   
   public static void main(String[] args) {
 
      EJBTester ejbTester = new EJBTester();
 
      ejbTester.testStatelessEjb();
   }
   
   private void showGUI() {
      System.out.println("**********************");
      System.out.println("Welcome to Book Store");
      System.out.println("**********************");
      System.out.print("Options \n1. Add Book\n2. Exit \nEnter Choice: ");
   }
   
   private void testStatelessEjb() {
 
      try {
         int choice = 1; 
 
         LibrarySessionBeanRemote libraryBean =
         LibrarySessionBeanRemote)ctx.lookup("LibrarySessionBean/remote");
 
         while (choice != 2) {
            String bookName;
            showGUI();
            String strChoice = brConsoleReader.readLine();
            choice = Integer.parseInt(strChoice);
            if (choice == 1) {
               System.out.print("Enter book name: ");
               bookName = brConsoleReader.readLine();
               Book book = new Book();
               book.setName(bookName);
               libraryBean.addBook(book);          
            } else if (choice == 2) {
               break;
            }
         }
 
         List<Book> booksList = libraryBean.getBooks();
 
         System.out.println("Book(s) entered so far: " + booksList.size());
         int i = 0;
         for (Book book:booksList) {
            System.out.println((i+1)+". " + book.getName());
            i++;
         }       
         LibrarySessionBeanRemote libraryBean1 = 
            (LibrarySessionBeanRemote)ctx.lookup("LibrarySessionBean/remote");
         List<String> booksList1 = libraryBean1.getBooks();
         System.out.println(
            "***Using second lookup to get library stateless object***");
         System.out.println(
            "Book(s) entered so far: " + booksList1.size());
         for (int i = 0; i < booksList1.size(); ++i) {
            System.out.println((i+1)+". " + booksList1.get(i));
         }		 
      } catch (Exception e) {
         System.out.println(e.getMessage());
         e.printStackTrace();
      }finally {
         try {
            if(brConsoleReader !=null) {
               brConsoleReader.close();
            }
         } catch (IOException ex) {
            System.out.println(ex.getMessage());
         }
      }
   }
}

EJBTester ดำเนินการดังต่อไปนี้ -

  • โหลดคุณสมบัติจาก jndi.properties และเริ่มต้นอ็อบเจ็กต์ InitialContext

  • ในเมธอด testStatelessEjb () การค้นหา jndi จะดำเนินการด้วยชื่อ - "LibrarySessionBean / remote" เพื่อรับอ็อบเจ็กต์ธุรกิจระยะไกล (stateless ejb)

  • จากนั้นผู้ใช้จะแสดงส่วนติดต่อผู้ใช้ที่เก็บไลบรารีและระบบจะขอให้ป้อนตัวเลือก

  • หากผู้ใช้ป้อน 1 ระบบจะถามชื่อหนังสือและบันทึกหนังสือโดยใช้วิธี stateless session bean addBook () Session Bean กำลังจัดเก็บหนังสือในตัวแปรอินสแตนซ์

  • หากผู้ใช้ป้อน 2 ระบบจะดึงหนังสือโดยใช้เมธอด getBooks () เซสชัน bean แบบไม่ระบุสถานะและออก

  • จากนั้นค้นหา jndi อีกครั้งด้วยชื่อ - "LibrarySessionBean / remote" เพื่อรับวัตถุทางธุรกิจระยะไกล (EJB ไร้สัญชาติ) อีกครั้งและทำรายการหนังสือ

เรียกใช้ไคลเอ็นต์เพื่อเข้าถึง EJB

ค้นหา EJBTester.java ใน project explorer คลิกขวาที่คลาส EJBTester และเลือกrun file.

ตรวจสอบเอาต์พุตต่อไปนี้ในคอนโซล Netbeans

run:
**********************
Welcome to Book Store
**********************
Options 
1. Add Book
2. Exit 
Enter Choice: 1
Enter book name: Learn Java
**********************
Welcome to Book Store
**********************
Options 
1. Add Book
2. Exit 
Enter Choice: 2
Book(s) entered so far: 1
1. Learn Java
***Using second lookup to get library stateless object***
Book(s) entered so far: 0
BUILD SUCCESSFUL (total time: 13 seconds)

เรียกใช้ไคลเอ็นต์อีกครั้งเพื่อเข้าถึง EJB

ค้นหา EJBTester.java ใน project explorer คลิกขวาที่คลาส EJBTester และเลือกrun file.

ตรวจสอบเอาต์พุตต่อไปนี้ในคอนโซล Netbeans

run:
**********************
Welcome to Book Store
**********************
Options 
1. Add Book
2. Exit 
Enter Choice: 2
Book(s) entered so far: 0
***Using second lookup to get library stateless object***
Book(s) entered so far: 1
1. Learn Java
BUILD SUCCESSFUL (total time: 12 seconds)
  • ผลลัพธ์ที่แสดงด้านบนอาจแตกต่างกันไปขึ้นอยู่กับว่า JBoss อ็อบเจ็กต์ EJB ที่ไม่ระบุสถานะกำลังคงอยู่จำนวนเท่าใด

  • ในกรณีที่มีการเก็บรักษาอ็อบเจ็กต์ EJB ที่ไม่มีสถานะเพียงรายการเดียวคุณอาจเห็นรายการหนังสือเดียวกันหลังจากการค้นหาแต่ละครั้ง

  • EJB Container อาจส่งคืนอ็อบเจ็กต์ EJB แบบไม่ระบุสถานะเดียวกันสำหรับการค้นหาทุกครั้ง

  • Stateless EJB bean กำลังเก็บค่าของตัวแปรอินสแตนซ์จนกว่าเซิร์ฟเวอร์จะไม่รีสตาร์ท

stateful session bean คือเอ็นเตอร์ไพรส์บีนประเภทหนึ่งซึ่งรักษาสถานะการสนทนากับไคลเอนต์ เซสชัน bean ที่มีสถานะตามชื่อจะเก็บสถานะไคลเอนต์ที่เกี่ยวข้องไว้ในตัวแปรอินสแตนซ์ EJB Container สร้างเซสชัน bean แบบ stateful แยกต่างหากเพื่อประมวลผลคำขอแต่ละรายการของไคลเอ็นต์ ทันทีที่ขอบเขตการร้องขอสิ้นสุดลงเซสชั่นบีน statelful จะถูกทำลาย

ขั้นตอนในการสร้าง Stateful EJB

ต่อไปนี้เป็นขั้นตอนที่จำเป็นในการสร้าง EJB ที่มีสถานะ -

  • สร้างอินเทอร์เฟซระยะไกล / โลคัลเพื่อเปิดเผยวิธีการทางธุรกิจ

  • อินเทอร์เฟซนี้จะถูกใช้โดยแอปพลิเคชันไคลเอนต์ EJB

  • ใช้คำอธิบายประกอบ @Local หากไคลเอ็นต์ EJB อยู่ในสภาพแวดล้อมเดียวกันกับที่ต้องปรับใช้เซสชันถั่ว EJB

  • ใช้คำอธิบายประกอบ @Remote หากไคลเอ็นต์ EJB อยู่ในสภาพแวดล้อมที่แตกต่างกันซึ่งจำเป็นต้องปรับใช้เซสชันถั่ว EJB

  • สร้างเซสชัน bean แบบ stateful โดยใช้อินเทอร์เฟซด้านบน

  • ใช้คำอธิบายประกอบ @Stateful เพื่อแสดงว่าเป็นถั่วที่มีสถานะ EJB Container จะสร้างคอนฟิกูเรชันหรืออินเทอร์เฟซที่เกี่ยวข้องโดยอัตโนมัติโดยอ่านคำอธิบายประกอบนี้ระหว่างการปรับใช้

อินเทอร์เฟซระยะไกล

import javax.ejb.Remote;
 
@Remote
public interface LibraryStatefulSessionBeanRemote {
   //add business method declarations
}

EJB ที่มีสถานะ

@Stateful
public class LibraryStatefulSessionBean implements LibraryStatefulSessionBeanRemote {
   //implement business method 
}

ตัวอย่างการใช้งาน

ให้เราสร้างแอปพลิเคชันทดสอบ EJB เพื่อทดสอบ EJB ที่มีสถานะ

ขั้นตอน คำอธิบาย
1

สร้างโครงการที่มีชื่อEjbComponentภายใต้แพคเกจcom.tutorialspoint.statefulตามที่อธิบายไว้ในEJB - สร้างแอพลิเคชันบท คุณยังสามารถใช้โปรเจ็กต์ที่สร้างในEJB - สร้างบทแอปพลิเคชันสำหรับบทนี้เพื่อทำความเข้าใจแนวคิด EJB ที่มีสถานะ

2

สร้างLibraryStatefulSessionBean.javaและLibraryStatefulSessionBeanRemoteตามที่อธิบายไว้ในEJB - สร้างแอพลิเคชันบท เก็บไฟล์ที่เหลือไว้ไม่เปลี่ยนแปลง

3

ทำความสะอาดและสร้างแอปพลิเคชันเพื่อให้แน่ใจว่าตรรกะทางธุรกิจทำงานได้ตามข้อกำหนด

4

สุดท้ายปรับใช้แอปพลิเคชันในรูปแบบของไฟล์ jar บน JBoss Application Server เซิร์ฟเวอร์แอปพลิเคชัน JBoss จะเริ่มทำงานโดยอัตโนมัติหากยังไม่เริ่มทำงาน

5

ตอนนี้สร้างไคลเอนต์ EJB ซึ่งเป็นแอปพลิเคชันบนคอนโซลในลักษณะเดียวกับที่อธิบายไว้ในบทEJB - Create Applicationภายใต้หัวข้อCreate Client to access EJB.

ส่วนประกอบ EJBC (โมดูล EJB)

LibraryStatefulSessionBeanRemote.java

package com.tutorialspoint.stateful;
 
import java.util.List;
import javax.ejb.Remote;
 
@Remote
public interface LibraryStatefulSessionBeanRemote {
   void addBook(String bookName);
   List getBooks();
}

LibraryStatefulSessionBean.java

package com.tutorialspoint.stateful;
 
import java.util.ArrayList;
import java.util.List;
import javax.ejb.Stateful;
 
@Stateful
public class LibraryStatefulSessionBean implements LibraryStatefulSessionBeanRemote {
    
   List<String> bookShelf;    
 
   public LibraryStatefulSessionBean() {
      bookShelf = new ArrayList<String>();
   }
 
   public void addBook(String bookName) {
      bookShelf.add(bookName);
   }    
 
   public List<String> getBooks() {
      return bookShelf;
   }
}
  • ทันทีที่คุณปรับใช้โครงการ EjbComponent บน JBOSS ให้สังเกตบันทึก jboss

  • JBoss ได้สร้างรายการ JNDI สำหรับถั่วเซสชันของเราโดยอัตโนมัติ - LibraryStatefulSessionBean/remote.

  • เราจะใช้สตริงการค้นหานี้เพื่อรับวัตถุทางธุรกิจระยะไกลประเภท - com.tutorialspoint.stateful.LibraryStatefulSessionBeanRemote

เอาต์พุตบันทึกของเซิร์ฟเวอร์แอปพลิเคชัน JBoss

...
16:30:01,401 INFO  [JndiSessionRegistrarBase] Binding the following Entries in Global JNDI:
   LibraryStatefulSessionBean/remote - EJB3.x Default Remote Business Interface
   LibraryStatefulSessionBean/remote-com.tutorialspoint.stateful.LibraryStatefulSessionBeanRemote - EJB3.x Remote Business Interface
16:30:02,723 INFO  [SessionSpecContainer] Starting jboss.j2ee:jar=EjbComponent.jar,name=LibraryStatefulSessionBean,service=EJB3
16:30:02,723 INFO  [EJBContainer] STARTED EJB: com.tutorialspoint.stateful.LibraryStatefulSessionBeanRemote ejbName: LibraryStatefulSessionBean
16:30:02,731 INFO  [JndiSessionRegistrarBase] Binding the following Entries in Global JNDI:
 
   LibraryStatefulSessionBean/remote - EJB3.x Default Remote Business Interface
   LibraryStatefulSessionBean/remote-com.tutorialspoint.stateful.LibraryStatefulSessionBeanRemote - EJB3.x Remote Business Interface
...

EJBTester (ไคลเอนต์ EJB)

jndi.properties

java.naming.factory.initial = org.jnp.interfaces.NamingContextFactory
java.naming.factory.url.pkgs = org.jboss.naming:org.jnp.interfaces
java.naming.provider.url = localhost
  • คุณสมบัติเหล่านี้ใช้เพื่อเริ่มต้นอ็อบเจ็กต์ InitialContext ของบริการการตั้งชื่อ java

  • วัตถุ InitialContext จะถูกใช้เพื่อค้นหาเซสชัน bean ที่มีสถานะ

EJBTester.java

package com.tutorialspoint.test;
   
import com.tutorialspoint.stateful.LibraryStatefulSessionBeanRemote;
import java.io.BufferedReader;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.List;
import java.util.Properties;
import javax.naming.InitialContext;
import javax.naming.NamingException;
 
public class EJBTester {
 
   BufferedReader brConsoleReader = null; 
   Properties props;
   InitialContext ctx;
   {
      props = new Properties();
      try {
         props.load(new FileInputStream("jndi.properties"));
      } catch (IOException ex) {
         ex.printStackTrace();
      }
      try {
         ctx = new InitialContext(props);            
      } catch (NamingException ex) {
         ex.printStackTrace();
      }
      brConsoleReader = 
      new BufferedReader(new InputStreamReader(System.in));
   }
   
   public static void main(String[] args) {
 
      EJBTester ejbTester = new EJBTester();
 
      ejbTester.testStatelessEjb();
   }
   
   private void showGUI() {
      System.out.println("**********************");
      System.out.println("Welcome to Book Store");
      System.out.println("**********************");
      System.out.print("Options \n1. Add Book\n2. Exit \nEnter Choice: ");
   }
   
   private void testStatelessEjb() {
 
      try {
         int choice = 1; 
 
         LibraryStatefulSessionBeanRemote libraryBean =
         LibraryStatefulSessionBeanRemote)ctx.lookup("LibraryStatefulSessionBean/remote");
 
         while (choice != 2) {
            String bookName;
            showGUI();
            String strChoice = brConsoleReader.readLine();
            choice = Integer.parseInt(strChoice);
            if (choice == 1) {
               System.out.print("Enter book name: ");
               bookName = brConsoleReader.readLine();
               Book book = new Book();
               book.setName(bookName);
               libraryBean.addBook(book);          
            } else if (choice == 2) {
               break;
            }
         }
 
         List<Book> booksList = libraryBean.getBooks();
 
         System.out.println("Book(s) entered so far: " + booksList.size());
         int i = 0;
         for (Book book:booksList) {
            System.out.println((i+1)+". " + book.getName());
            i++;
         }       
         LibraryStatefulSessionBeanRemote libraryBean1 = 
            (LibraryStatefulSessionBeanRemote)ctx.lookup("LibraryStatefulSessionBean/remote");
         List<String> booksList1 = libraryBean1.getBooks();
         System.out.println(
            "***Using second lookup to get library stateful object***");
         System.out.println(
            "Book(s) entered so far: " + booksList1.size());
         for (int i = 0; i < booksList1.size(); ++i) {
            System.out.println((i+1)+". " + booksList1.get(i));
         }		 
      } catch (Exception e) {
         System.out.println(e.getMessage());
         e.printStackTrace();
      }finally {
         try {
            if(brConsoleReader !=null) {
               brConsoleReader.close();
            }
         } catch (IOException ex) {
            System.out.println(ex.getMessage());
         }
      }
   }
}

EJBTester ดำเนินการดังต่อไปนี้ -

  • โหลดคุณสมบัติจาก jndi.properties และเริ่มต้นอ็อบเจ็กต์ InitialContext

  • ในเมธอด testStatefulEjb () การค้นหา jndi จะทำด้วยชื่อ - "LibraryStatefulSessionBean / remote" เพื่อรับวัตถุทางธุรกิจระยะไกล (stateful ejb)

  • จากนั้นผู้ใช้จะแสดงส่วนติดต่อผู้ใช้ที่เก็บไลบรารีและระบบจะขอให้ผู้ใช้ป้อนตัวเลือก

  • หากผู้ใช้ป้อน 1 ระบบจะถามชื่อหนังสือและบันทึกหนังสือโดยใช้วิธี stateful session bean addBook () Session Bean กำลังจัดเก็บหนังสือในตัวแปรอินสแตนซ์

  • หากผู้ใช้ป้อน 2 ระบบจะดึงหนังสือโดยใช้เมธอด getBooks () ของเซสชัน bean () และออก

  • จากนั้นค้นหา jndi อีกครั้งด้วยชื่อ - "LibraryStatefulSessionBean / remote" เพื่อรับวัตถุทางธุรกิจระยะไกล (EJB ที่มีสถานะ) อีกครั้งและทำรายการหนังสือ

เรียกใช้ไคลเอ็นต์เพื่อเข้าถึง EJB

ค้นหา EJBTester.java ใน project explorer คลิกขวาที่คลาส EJBTester และเลือกrun file.

ตรวจสอบเอาต์พุตต่อไปนี้ในคอนโซล Netbeans -

run:
**********************
Welcome to Book Store
**********************
Options 
1. Add Book
2. Exit 
Enter Choice: 1
Enter book name: Learn Java
**********************
Welcome to Book Store
**********************
Options 
1. Add Book
2. Exit 
Enter Choice: 2
Book(s) entered so far: 1
1. Learn Java
***Using second lookup to get library stateful object***
Book(s) entered so far: 0
BUILD SUCCESSFUL (total time: 13 seconds)

เรียกใช้ไคลเอ็นต์อีกครั้งเพื่อเข้าถึง EJB

ค้นหา EJBTester.java ใน project explorer คลิกขวาที่คลาส EJBTester และเลือกrun file.

ตรวจสอบเอาต์พุตต่อไปนี้ในคอนโซล Netbeans

run:
**********************
Welcome to Book Store
**********************
Options 
1. Add Book
2. Exit 
Enter Choice: 2
Book(s) entered so far: 0
***Using second lookup to get library stateful object***
Book(s) entered so far: 0
BUILD SUCCESSFUL (total time: 12 seconds)
  • ผลลัพธ์ที่แสดงด้านบนระบุว่าสำหรับการค้นหาแต่ละครั้งจะมีการส่งคืนอินสแตนซ์ EJB แบบ stateful ที่แตกต่างกัน

  • ออบเจ็กต์ Stateful EJB กำลังเก็บค่าไว้สำหรับเซสชันเดียวเท่านั้น ในระยะที่สองเราไม่ได้รับคุณค่าใด ๆ จากหนังสือ

EJB 3.0 เอนทิตี bean ที่ใช้ใน EJB 2.0 ส่วนใหญ่ถูกแทนที่ด้วยกลไกการคงอยู่ ตอนนี้เอนทิตี bean เป็น POJO ธรรมดาที่มีการแมปกับตาราง

ต่อไปนี้เป็นตัวแสดงหลักใน Persistence API -

  • Entity- ออบเจ็กต์ถาวรที่แสดงถึงบันทึกการจัดเก็บข้อมูล เป็นเรื่องดีที่จะทำให้เป็นอนุกรมได้

  • EntityManager- อินเทอร์เฟซการคงอยู่เพื่อดำเนินการข้อมูลเช่นเพิ่ม / ลบ / อัปเดต / ค้นหาบนวัตถุถาวร (เอนทิตี) นอกจากนี้ยังช่วยดำเนินการสืบค้นโดยใช้Query อินเตอร์เฟซ.

  • Persistence unit (persistence.xml) - หน่วยความคงอยู่อธิบายคุณสมบัติของกลไกการคงอยู่

  • Data Source (*ds.xml)- แหล่งข้อมูลอธิบายคุณสมบัติที่เกี่ยวข้องกับการจัดเก็บข้อมูลเช่น url การเชื่อมต่อ ชื่อผู้ใช้รหัสผ่าน ฯลฯ

เพื่อแสดงให้เห็นถึงกลไกการคงอยู่ของ EJB เราจำเป็นต้องทำภารกิจต่อไปนี้ -

  • Step 1 - สร้างตารางในฐานข้อมูล

  • Step 2 - สร้างคลาสเอนทิตีที่สอดคล้องกับตาราง

  • Step 3 - สร้างแหล่งข้อมูลและหน่วยความคงอยู่

  • Step 4 - สร้าง EJB ไร้สัญชาติที่มีอินสแตนซ์ EntityManager

  • Step 5- อัปเดต EJB ไร้สัญชาติ เพิ่มวิธีการเพิ่มเรกคอร์ดและรับเรกคอร์ดจากฐานข้อมูลผ่านตัวจัดการเอนทิตี

  • Step 6 - ไคลเอนต์แอปพลิเคชันที่ใช้คอนโซลจะเข้าถึง EJB แบบไม่ระบุสถานะเพื่อคงข้อมูลในฐานข้อมูล

สร้างตาราง

สร้างตาราง books ในฐานข้อมูลเริ่มต้น postgres.

CREATE TABLE books (
   id     integer PRIMARY KEY,
   name   varchar(50)
);

สร้างคลาสเอนทิตี

//mark it entity using Entity annotation 
//map table name using Table annotation
@Entity
@Table(name="books")
public class Book implements Serializable{
    
   private int id;
   private String name;

   public Book() {        
   }

   //mark id as primary key with autogenerated value
   //map database column id with id field
   @Id
   @GeneratedValue(strategy= GenerationType.IDENTITY)
   @Column(name="id")
   public int getId() {
      return id;
   }
   ...
}

สร้างแหล่งข้อมูลและหน่วยความคงอยู่

แหล่งข้อมูล (jboss-ds.xml)

<?xml version = "1.0" encoding = "UTF-8"?>
<datasources>
   <local-tx-datasource>
      <jndi-name>PostgresDS</jndi-name>
      <connection-url>jdbc:postgresql://localhost:5432/postgres</connection-url>
      <driver-class>org.postgresql.driver</driver-class>
      <user-name>sa</user-name>
      <password>sa</password>
      <min-pool-size>5</min-pool-size>
      <max-pool-size>20</max-pool-size>
      <idle-timeout-minutes>5</idle-timeout-minutes>
   </local-tx-datasource>
</datasources>

หน่วยความคงอยู่ (persistence.xml)

<persistence version = "1.0" xmlns = "http://java.sun.com/xml/ns/persistence" xmlns:xsi = "http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/persistence http://java.sun.com/xml/ns/persistence/persistence_1_0.xsd">

   <persistence-unit name = "EjbComponentPU" transaction-type = "JTA">
      <jta-data-source>java:/PostgresDS</jta-data-source>
      <exclude-unlisted-classes>false</exclude-unlisted-classes>
      <properties/>
   </persistence-unit>
   
   <persistence-unit name = "EjbComponentPU2" transaction-type = "JTA">
      <provider>org.hibernate.ejb.HibernatePersistence</provider>
      <jta-data-source>java:/PostgresDS</jta-data-source>
      <exclude-unlisted-classes>false</exclude-unlisted-classes>
	  
      <properties>
         <property name="hibernate.hbm2ddl.auto" value="update"/>
      </properties>
   </persistence-unit>
   
</persistence>

สร้าง EJB แบบไม่ระบุสถานะโดยมีอินสแตนซ์ EntityManager

@Stateless
public class LibraryPersistentBean implements LibraryPersistentBeanRemote {
	
   //pass persistence unit to entityManager.
   @PersistenceContext(unitName="EjbComponentPU")
   private EntityManager entityManager;         

   public void addBook(Book book) {
      entityManager.persist(book);
   }    

   public List<Book> getBooks() {        
      return entityManager.createQuery("From Books").getResultList();
   }
   ...
}

หลังจากสร้างโมดูล EJB แล้วเราจำเป็นต้องมีไคลเอนต์เพื่อเข้าถึงถั่วไร้สัญชาติซึ่งเราจะสร้างในส่วนถัดไป

ตัวอย่างการใช้งาน

ให้เราสร้างแอปพลิเคชันทดสอบ EJB เพื่อทดสอบกลไกการคงอยู่ของ EJB

ขั้นตอน คำอธิบาย
1

สร้างโครงการที่มีชื่อEjbComponentภายใต้แพคเกจcom.tutorialspoint.entityตามที่อธิบายไว้ในEJB - สร้างแอพลิเคชันบท คุณยังสามารถใช้โครงการที่สร้างในEJB - สร้างบทแอปพลิเคชันสำหรับบทนี้เพื่อทำความเข้าใจแนวคิดการคงอยู่ของ EJB

2

สร้างBook.javaภายใต้แพ็คเกจcom.tutorialspoint.entityและแก้ไขตามที่แสดงด้านล่าง

3

สร้างLibraryPersistentBean.javaและLibraryPersistentBeanRemoteตามที่อธิบายไว้ในEJB - สร้างบทApplicationและแก้ไขตามที่แสดงด้านล่าง

4

สร้างjboss-ds.xmlในEjbComponent > setup โฟลเดอร์และpersistence.xmlในEjbComponent > src > conf โฟลเดอร์ โฟลเดอร์เหล่านี้สามารถเห็นได้ในแท็บไฟล์ใน Netbeans แก้ไขไฟล์เหล่านี้ตามที่แสดงด้านบน

5

ทำความสะอาดและสร้างแอปพลิเคชันเพื่อให้แน่ใจว่าตรรกะทางธุรกิจทำงานได้ตามข้อกำหนด

6

สุดท้ายปรับใช้แอปพลิเคชันในรูปแบบของไฟล์ jar บน JBoss Application Server เซิร์ฟเวอร์แอปพลิเคชัน JBoss จะเริ่มทำงานโดยอัตโนมัติหากยังไม่เริ่มทำงาน

7

ตอนนี้สร้างไคลเอนต์ EJB ซึ่งเป็นแอปพลิเคชันบนคอนโซลในลักษณะเดียวกับที่อธิบายไว้ในบทEJB - Create Applicationภายใต้หัวข้อCreate Client to access EJB. แก้ไขตามที่แสดงด้านล่าง

ส่วนประกอบ EJBC (โมดูล EJB)

Book.java

package com.tutorialspoint.entity;

import java.io.Serializable;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.EntityListeners;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.Table;

@Entity
@Table(name="books")
public class Book implements Serializable{
    
   private int id;
   private String name;

   public Book() {        
   }

   @Id
   @GeneratedValue(strategy= GenerationType.IDENTITY)
   @Column(name="id")
   public int getId() {
      return id;
   }

   public void setId(int id) {
      this.id = id;
   }

   public String getName() {
      return name;
   }

   public void setName(String name) {
      this.name = name;
   }    
}

LibraryPersistentBeanRemote.java

package com.tutorialspoint.stateless;

import com.tutorialspoint.entity.Book;
import java.util.List;
import javax.ejb.Remote;

@Remote
public interface LibraryPersistentBeanRemote {

   void addBook(Book bookName);

   List<Book> getBooks();
    
}

LibraryPersistentBean.java

package com.tutorialspoint.stateless;

import com.tutorialspoint.entity.Book;
import java.util.List;
import javax.ejb.Stateless;
import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;

@Stateless
public class LibraryPersistentBean implements LibraryPersistentBeanRemote {
    
   public LibraryPersistentBean() {
   }

   @PersistenceContext(unitName="EjbComponentPU")
   private EntityManager entityManager;         

   public void addBook(Book book) {
      entityManager.persist(book);
   }    

   public List<Book> getBooks() {
      return entityManager.createQuery("From Book").getResultList();
   }
}
  • ทันทีที่คุณปรับใช้โครงการ EjbComponent บน JBOSS ให้สังเกตบันทึก jboss

  • JBoss ได้สร้างรายการ JNDI สำหรับถั่วเซสชันของเราโดยอัตโนมัติ - LibraryPersistentBean/remote.

  • เราจะใช้สตริงการค้นหานี้เพื่อรับวัตถุทางธุรกิจระยะไกลประเภท - com.tutorialspoint.stateless.LibraryPersistentBeanRemote

เอาต์พุตบันทึกของเซิร์ฟเวอร์แอปพลิเคชัน JBoss

...
16:30:01,401 INFO  [JndiSessionRegistrarBase] Binding the following Entries in Global JNDI:
   LibraryPersistentBean/remote - EJB3.x Default Remote Business Interface
   LibraryPersistentBean/remote-com.tutorialspoint.stateless.LibraryPersistentBeanRemote - EJB3.x Remote Business Interface
16:30:02,723 INFO  [SessionSpecContainer] Starting jboss.j2ee:jar=EjbComponent.jar,name=LibraryPersistentBeanRemote,service=EJB3
16:30:02,723 INFO  [EJBContainer] STARTED EJB: com.tutorialspoint.stateless.LibraryPersistentBeanRemote ejbName: LibraryPersistentBean
16:30:02,731 INFO  [JndiSessionRegistrarBase] Binding the following Entries in Global JNDI:

   LibraryPersistentBean/remote - EJB3.x Default Remote Business Interface
   LibraryPersistentBean/remote-com.tutorialspoint.stateless.LibraryPersistentBeanRemote - EJB3.x Remote Business Interface
...

EJBTester (ไคลเอนต์ EJB)

jndi.properties

java.naming.factory.initial=org.jnp.interfaces.NamingContextFactory
java.naming.factory.url.pkgs=org.jboss.naming:org.jnp.interfaces
java.naming.provider.url=localhost
  • คุณสมบัติเหล่านี้ใช้เพื่อเริ่มต้นอ็อบเจ็กต์ InitialContext ของบริการการตั้งชื่อ java

  • วัตถุ InitialContext จะถูกใช้เพื่อค้นหาเซสชัน bean ที่ไม่มีสถานะ

EJBTester.java

package com.tutorialspoint.test;
   
import com.tutorialspoint.stateless.LibraryPersistentBeanRemote;
import java.io.BufferedReader;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.List;
import java.util.Properties;
import javax.naming.InitialContext;
import javax.naming.NamingException;

public class EJBTester {

   BufferedReader brConsoleReader = null; 
   Properties props;
   InitialContext ctx;
   {
      props = new Properties();
      try {
         props.load(new FileInputStream("jndi.properties"));
      } catch (IOException ex) {
         ex.printStackTrace();
      }
      try {
         ctx = new InitialContext(props);            
      } catch (NamingException ex) {
         ex.printStackTrace();
      }
      brConsoleReader = 
      new BufferedReader(new InputStreamReader(System.in));
   }
   
   public static void main(String[] args) {

      EJBTester ejbTester = new EJBTester();

      ejbTester.testEntityEjb();
   }
   
   private void showGUI() {
      System.out.println("**********************");
      System.out.println("Welcome to Book Store");
      System.out.println("**********************");
      System.out.print("Options \n1. Add Book\n2. Exit \nEnter Choice: ");
   }
   
   private void testEntityEjb() {

      try {
         int choice = 1; 

         LibraryPersistentBeanRemote libraryBean =
         LibraryPersistentBeanRemote)ctx.lookup("LibraryPersistentBean/remote");

         while (choice != 2) {
            String bookName;
            showGUI();
            String strChoice = brConsoleReader.readLine();
            choice = Integer.parseInt(strChoice);
            if (choice == 1) {
               System.out.print("Enter book name: ");
               bookName = brConsoleReader.readLine();
               Book book = new Book();
               book.setName(bookName);
               libraryBean.addBook(book);          
            } else if (choice == 2) {
               break;
            }
         }

         List<Book> booksList = libraryBean.getBooks();

         System.out.println("Book(s) entered so far: " + booksList.size());
         int i = 0;
         for (Book book:booksList) {
            System.out.println((i+1)+". " + book.getName());
            i++;
         }           
      } catch (Exception e) {
         System.out.println(e.getMessage());
         e.printStackTrace();
      }finally {
         try {
            if(brConsoleReader !=null) {
               brConsoleReader.close();
            }
         } catch (IOException ex) {
            System.out.println(ex.getMessage());
         }
      }
   }
}

EJBTester ดำเนินการต่อไปนี้

  • โหลดคุณสมบัติจาก jndi.properties และเริ่มต้นอ็อบเจ็กต์ InitialContext

  • ในเมธอด testStatefulEjb () การค้นหา jndi จะทำด้วยชื่อ - "LibraryStatefulSessionBean / remote" เพื่อรับวัตถุทางธุรกิจระยะไกล (stateful ejb)

  • จากนั้นผู้ใช้จะแสดงส่วนติดต่อผู้ใช้ที่เก็บไลบรารีและระบบจะขอให้ป้อนตัวเลือก

  • หากผู้ใช้ป้อน 1 ระบบจะถามชื่อหนังสือและบันทึกหนังสือโดยใช้วิธี stateless session bean addBook () Session Bean ยังคงมีหนังสืออยู่ในฐานข้อมูลผ่านการเรียก EntityManager

  • หากผู้ใช้ป้อน 2 ระบบจะดึงหนังสือโดยใช้เมธอด getBooks () ของเซสชัน bean () และออก

  • จากนั้นค้นหา jndi อีกครั้งโดยใช้ชื่อ - "LibraryStatelessSessionBean / remote" เพื่อรับวัตถุทางธุรกิจระยะไกล (EJB ไร้สัญชาติ) อีกครั้งและทำรายการหนังสือ

เรียกใช้ไคลเอ็นต์เพื่อเข้าถึง EJB

ค้นหา EJBTester.java ใน project explorer คลิกขวาที่คลาส EJBTester และเลือกrun file.

ตรวจสอบเอาต์พุตต่อไปนี้ในคอนโซล Netbeans -

run:
**********************
Welcome to Book Store
**********************
Options 
1. Add Book
2. Exit 
Enter Choice: 1
Enter book name: Learn Java
**********************
Welcome to Book Store
**********************
Options 
1. Add Book
2. Exit 
Enter Choice: 2
Book(s) entered so far: 1
1. learn java
BUILD SUCCESSFUL (total time: 15 seconds)

เรียกใช้ไคลเอ็นต์อีกครั้งเพื่อเข้าถึง EJB

รีสตาร์ท JBoss ก่อนเข้าถึง EJB

ค้นหา EJBTester.java ใน project explorer คลิกขวาที่คลาส EJBTester และเลือกrun file.

ตรวจสอบเอาต์พุตต่อไปนี้ในคอนโซล Netbeans

run:
**********************
Welcome to Book Store
**********************
Options 
1. Add Book
2. Exit 
Enter Choice: 1
Enter book name: Learn Spring
**********************
Welcome to Book Store
**********************
Options 
1. Add Book
2. Exit 
Enter Choice: 2
Book(s) entered so far: 2
1. learn java
2. Learn Spring
BUILD SUCCESSFUL (total time: 15 seconds)

ผลลัพธ์ที่แสดงด้านบนระบุว่าหนังสือกำลังถูกจัดเก็บในที่จัดเก็บถาวรและถูกดึงมาจากฐานข้อมูล

ข้อความที่ขับเคลื่อนด้วย bean คือเอ็นเตอร์ไพรส์บีนชนิดหนึ่งซึ่งเรียกใช้โดยคอนเทนเนอร์ EJB เมื่อได้รับข้อความจากคิวหรือหัวข้อ Message driven bean เป็นถั่วไร้สถานะและใช้เพื่อทำงานแบบอะซิงโครนัส

เพื่อแสดงให้เห็นถึงการใช้ถั่วที่ขับเคลื่อนด้วยข้อความเราจะใช้ประโยชน์จากบทการคงอยู่ของ EJB และเราจำเป็นต้องทำงานต่อไปนี้ -

  • Step 1- สร้างตารางในฐานข้อมูล (อ้างอิงจากบทEJB-Persistence )

  • Step 2- สร้างคลาสเอนทิตีที่สอดคล้องกับตาราง (อ้างอิงจากบทEJB-Persistence )

  • Step 3- สร้างแหล่งข้อมูลและหน่วยความคงอยู่ (อ้างอิงจากบทEJB-Persistence )

  • Step 4- สร้าง EJB ไร้สัญชาติที่มีอินสแตนซ์ EntityManager (อ้างอิงจากบทEJB-Persistence )

  • Step 5- อัปเดต ejb ไร้สัญชาติเพิ่มวิธีการในการเพิ่มบันทึกและรับบันทึกจากฐานข้อมูลผ่านตัวจัดการเอนทิตี (อ้างถึงบทEJB-Persistence )

  • Step 6 - สร้างคิวชื่อ BookQueue ใน JBoss default ไดเรกทอรีแอปพลิเคชัน

  • Step 7 - ไคลเอนต์แอปพลิเคชันที่ใช้คอนโซลจะส่งข้อความไปยังคิวนี้

  • Step 8 - สร้าง Message driven bean ซึ่งจะใช้ stateless bean เพื่อคงข้อมูลไคลเอนต์

  • Step 9 - EJB Container ของ jboss จะเรียกข้อความที่ขับเคลื่อนด้วยข้อความด้านบนและส่งต่อข้อความที่ลูกค้าจะส่งไป

สร้างคิว

สร้างไฟล์ชื่อ jbossmq-destination-service.xml หากไม่มีอยู่ใน <JBoss Installation Folder> > server > default > deploy โฟลเดอร์

ที่นี่เรากำลังสร้างคิวชื่อ BookQueue -

jbossmq-destination-service.xml

<mbean code="org.jboss.mq.server.jmx.Queue"  
   name="jboss.mq.destination:service=Queue,name=BookQueue">  
   <depends optional-attribute-name="DestinationManager">
      jboss.mq:service=DestinationManager
   </depends>  
</mbean>

เมื่อคุณเริ่ม JBoss คุณจะเห็นรายการที่คล้ายกันในบันทึก jboss

...
10:37:06,167 INFO  [QueueService] Queue[/queue/BookQueue] started, fullSize=200000, pageSize=2000, downCacheSize=2000
...

สร้าง Message Driven Bean

@MessageDriven(
   name = "BookMessageHandler",
   activationConfig = {
      @ActivationConfigProperty( propertyName = "destinationType", 
                                 propertyValue = "javax.jms.Queue"),
      @ActivationConfigProperty( propertyName = "destination", 
                                 propertyValue ="/queue/BookQueue")
   }
)
public class LibraryMessageBean implements MessageListener {
 
   @Resource
   private MessageDrivenContext mdctx;  
 
   @EJB
   LibraryPersistentBeanRemote libraryBean;
 
   public LibraryMessageBean() {        
   }
 
   public void onMessage(Message message) {
   }
}
  • LibraryMessageBean มีคำอธิบายประกอบ @MessageDriven เพื่อทำเครื่องหมายเป็นถั่วที่ขับเคลื่อนด้วยข้อความ

  • คุณสมบัติของมันถูกกำหนดเป็น destinationType - คิวและปลายทาง - / คิว / BookQueue

  • ใช้อินเทอร์เฟซ MessageListener ซึ่งแสดงเมธอด onMessage

  • มี MessgeDrivenContext เป็นทรัพยากร

  • LibraryPersistentBeanRemote stateless bean ถูกฉีดเข้าไปใน bean นี้เพื่อวัตถุประสงค์ในการคงอยู่

สร้างโครงการ EjbComponent และปรับใช้บน JBoss หลังจากสร้างและปรับใช้โมดูล EJB แล้วเราจำเป็นต้องมีไคลเอ็นต์เพื่อส่งข้อความไปยังคิว jboss

ตัวอย่างการใช้งาน

ให้เราสร้างแอปพลิเคชั่นทดสอบ EJB เพื่อทดสอบ Message Driven Bean

ขั้นตอน คำอธิบาย
1

สร้างโครงการที่มีชื่อEjbComponentภายใต้แพคเกจcom.tutorialspoint.entityตามที่อธิบายไว้ในEJB - สร้างแอพลิเคชันบท คุณยังสามารถใช้โครงการที่สร้างในEJB - สร้างบทแอปพลิเคชันสำหรับบทนี้เพื่อทำความเข้าใจแนวคิดการคงอยู่ของ EJB

2

สร้างBook.javaภายใต้ package com.tutorialspoint.entityตามที่สร้างในบทEJB-Persistence

3

สร้างLibraryPersistentBean.javaและLibraryPersistentBeanRemoteตามที่สร้างในบทEJB-Persistence

4

สร้างjboss-ds.xmlในEjbComponent > setup โฟลเดอร์และpersistence.xmlในEjbComponent > src > conf โฟลเดอร์ โฟลเดอร์เหล่านี้สามารถเห็นได้ในแท็บไฟล์ใน Netbeans ตามที่สร้างในบทEJB-Persistence

5

สร้างLibraryMessageBean.javaภายใต้แพ็คเกจcom.tutorialspoint.messagebeanและแก้ไขตามที่แสดงด้านล่าง

6

สร้างคิวBookQueue ใน Jbossตามที่อธิบายไว้ข้างต้น

7

ทำความสะอาดและสร้างแอปพลิเคชันเพื่อให้แน่ใจว่าตรรกะทางธุรกิจทำงานได้ตามข้อกำหนด

8

สุดท้ายปรับใช้แอปพลิเคชันในรูปแบบของไฟล์ jar บน JBoss Application Server เซิร์ฟเวอร์แอปพลิเคชัน JBoss จะเริ่มทำงานโดยอัตโนมัติหากยังไม่เริ่มทำงาน

9

ตอนนี้สร้างไคลเอนต์ EJB ซึ่งเป็นแอปพลิเคชันบนคอนโซลในลักษณะเดียวกับที่อธิบายไว้ในบทEJB - Create Applicationภายใต้หัวข้อCreate Client to access EJB. แก้ไขตามที่แสดงด้านล่าง

ส่วนประกอบ EJBC (โมดูล EJB)

LibraryMessageBean.java

package com.tutorialspoint.messagebean;
 
import com.tutorialspoint.entity.Book;
import com.tutorialspoint.stateless.LibraryPersistentBeanRemote;
import javax.annotation.Resource;
import javax.ejb.ActivationConfigProperty;
import javax.ejb.EJB;
import javax.ejb.MessageDriven;
import javax.ejb.MessageDrivenContext;
import javax.jms.JMSException;
import javax.jms.Message;
import javax.jms.MessageListener;
import javax.jms.ObjectMessage;
 
@MessageDriven(
   name = "BookMessageHandler",
   activationConfig = {
      @ActivationConfigProperty( propertyName = "destinationType", 
                                 propertyValue = "javax.jms.Queue"),
      @ActivationConfigProperty( propertyName = "destination", 
                                 propertyValue ="/queue/BookQueue")
   }
)
public class LibraryMessageBean implements MessageListener {
 
   @Resource
   private MessageDrivenContext mdctx;  
 
   @EJB
   LibraryPersistentBeanRemote libraryBean;
 
   public LibraryMessageBean() {        
   }
 
   public void onMessage(Message message) {
      ObjectMessage objectMessage = null;
      try {
         objectMessage = (ObjectMessage) message;
         Book book = (Book) objectMessage.getObject(); 
         libraryBean.addBook(book);
 
      } catch (JMSException ex) {
         mdctx.setRollbackOnly();
      }       
   }   
}

EJBTester (ไคลเอนต์ EJB)

EJBTester.java

package com.tutorialspoint.test;
   
import com.tutorialspoint.entity.Book;
import com.tutorialspoint.stateless.LibraryPersistentBeanRemote;
import java.io.BufferedReader;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.List;
import java.util.Properties;
import javax.jms.ObjectMessage;
import javax.jms.Queue;
import javax.jms.QueueConnection;
import javax.jms.QueueConnectionFactory;
import javax.jms.QueueSender;
import javax.jms.QueueSession;
import javax.naming.InitialContext;
import javax.naming.NamingException;
 
public class EJBTester {
 
   BufferedReader brConsoleReader = null; 
   Properties props;
   InitialContext ctx;
   {
      props = new Properties();
      try {
         props.load(new FileInputStream("jndi.properties"));
      } catch (IOException ex) {
         ex.printStackTrace();
      }
      try {
         ctx = new InitialContext(props);            
      } catch (NamingException ex) {
         ex.printStackTrace();
      }
      brConsoleReader = 
      new BufferedReader(new InputStreamReader(System.in));
   }
   
   public static void main(String[] args) {
 
      EJBTester ejbTester = new EJBTester();
 
      ejbTester.testMessageBeanEjb();
   }
   
   private void showGUI() {
      System.out.println("**********************");
      System.out.println("Welcome to Book Store");
      System.out.println("**********************");
      System.out.print("Options \n1. Add Book\n2. Exit \nEnter Choice: ");
   }
   
   private void testMessageBeanEjb() {
 
      try {
         int choice = 1; 
         Queue queue = (Queue) ctx.lookup("/queue/BookQueue");
         QueueConnectionFactory factory =
         (QueueConnectionFactory) ctx.lookup("ConnectionFactory");
         QueueConnection connection =  factory.createQueueConnection();
         QueueSession session = 
         connection.createQueueSession(false, QueueSession.AUTO_ACKNOWLEDGE);
         QueueSender sender = session.createSender(queue);
 
         while (choice != 2) {
            String bookName;
            showGUI();
            String strChoice = brConsoleReader.readLine();
            choice = Integer.parseInt(strChoice);
            if (choice == 1) {
               System.out.print("Enter book name: ");
               bookName = brConsoleReader.readLine();
               Book book = new Book();
               book.setName(bookName);
               ObjectMessage objectMessage = 
                  session.createObjectMessage(book);
               sender.send(objectMessage); 
            } else if (choice == 2) {
               break;
            }
         }
 
         LibraryPersistentBeanRemote libraryBean = 
         (LibraryPersistentBeanRemote)
         ctx.lookup("LibraryPersistentBean/remote");
 
         List<Book> booksList = libraryBean.getBooks();
 
         System.out.println("Book(s) entered so far: " + booksList.size());
         int i = 0;
         for (Book book:booksList) {
            System.out.println((i+1)+". " + book.getName());
            i++;
         }           
      } catch (Exception e) {
         System.out.println(e.getMessage());
         e.printStackTrace();
      }finally {
         try {
            if(brConsoleReader !=null) {
               brConsoleReader.close();
            }
         } catch (IOException ex) {
            System.out.println(ex.getMessage());
         }
      }
   }   
}

EJBTester ดำเนินการดังต่อไปนี้ -

  • โหลดคุณสมบัติจาก jndi.properties และเริ่มต้นอ็อบเจ็กต์ InitialContext

  • ในเมธอด testStatefulEjb () การค้นหา jndi จะดำเนินการโดยใช้ชื่อ - "/ que / BookQueue" เพื่อให้ได้ความยาวของคิวที่มีอยู่ใน Jboss จากนั้นผู้ส่งจะถูกสร้างขึ้นโดยใช้เซสชันคิว

  • จากนั้นผู้ใช้จะแสดงส่วนติดต่อผู้ใช้ที่เก็บไลบรารีและระบบจะขอให้ป้อนตัวเลือก

  • หากผู้ใช้ป้อน 1 ระบบจะถามชื่อหนังสือและผู้ส่งจะส่งชื่อหนังสือไปที่คิว เมื่อคอนเทนเนอร์ JBoss ได้รับข้อความนี้ในคิวจะเรียกใช้เมธอด onMessage ของถั่วที่ขับเคลื่อนด้วยข้อความ ข้อความของเราที่ขับเคลื่อนด้วย bean จะบันทึกหนังสือโดยใช้วิธี stateful session bean addBook () Session Bean ยังคงมีหนังสืออยู่ในฐานข้อมูลผ่านการเรียก EntityManager

  • หากผู้ใช้ป้อน 2 การค้นหา jndi อื่นจะถูกสร้างขึ้นด้วยชื่อ - "LibraryStatefulSessionBean / remote" เพื่อรับวัตถุทางธุรกิจระยะไกล (stateful EJB) อีกครั้งและทำรายการหนังสือ

เรียกใช้ไคลเอ็นต์เพื่อเข้าถึง EJB

ค้นหา EJBTester.java ใน project explorer คลิกขวาที่คลาส EJBTester และเลือกrun file.

ตรวจสอบเอาต์พุตต่อไปนี้ในคอนโซล Netbeans -

run:
**********************
Welcome to Book Store
**********************
Options 
1. Add Book
2. Exit 
Enter Choice: 1
Enter book name: Learn EJB
**********************
Welcome to Book Store
**********************
Options 
1. Add Book
2. Exit 
Enter Choice: 2
Book(s) entered so far: 2
1. learn java
1. learn EJB
BUILD SUCCESSFUL (total time: 15 seconds)

ผลลัพธ์ที่แสดงด้านบนระบุว่า Message driven bean ของเราได้รับข้อความและจัดเก็บหนังสือในที่จัดเก็บถาวรและหนังสือจะถูกดึงมาจากฐานข้อมูล

คำอธิบายประกอบถูกนำมาใช้ใน Java 5.0 วัตถุประสงค์ของการมีคำอธิบายประกอบคือการแนบข้อมูลเพิ่มเติมในคลาสหรือข้อมูลเมตาของคลาสภายในซอร์สโค้ด ใน EJB 3.0 คำอธิบายประกอบถูกใช้เพื่ออธิบายข้อมูลเมตาการกำหนดค่าในคลาส EJB ด้วยวิธีนี้ EJB 3.0 จึงไม่จำเป็นต้องอธิบายข้อมูลการกำหนดค่าในไฟล์ XML การกำหนดค่า

คอนเทนเนอร์ EJB ใช้เครื่องมือคอมไพเลอร์เพื่อสร้างสิ่งประดิษฐ์ที่จำเป็นเช่นอินเทอร์เฟซตัวบอกการปรับใช้โดยอ่านคำอธิบายประกอบเหล่านั้น ต่อไปนี้เป็นรายการคำอธิบายประกอบที่ใช้กันทั่วไป

Sr.no ชื่อ คำอธิบาย
1

javax.ejb.Stateless

ระบุว่าคลาส EJB ที่กำหนดคือเซสชัน bean ที่ไม่มีสถานะ

Attributes

  • name - ใช้เพื่อระบุชื่อของเซสชั่นบีน

  • mappedName - ใช้เพื่อระบุชื่อ JNDI ของเซสชั่นบีน

  • description - ใช้เพื่อให้คำอธิบายของเซสชั่นบีน

2

javax.ejb

ระบุว่าคลาส EJB ที่กำหนดคือเซสชัน bean แบบ stateful

Attributes

  • name - ใช้เพื่อระบุชื่อของเซสชั่นบีน

  • mappedName - ใช้เพื่อระบุชื่อ JNDI ของเซสชั่นบีน

  • description - ใช้เพื่อให้คำอธิบายของเซสชั่นบีน

3

javax.ejb.MessageDrivenBean

ระบุว่าคลาส EJB ที่กำหนดคือข้อความที่ขับเคลื่อนด้วย bean

Attributes

  • name - ใช้เพื่อระบุชื่อของข้อความที่ขับเคลื่อนด้วย bean

  • messageListenerInterface - ใช้เพื่อระบุอินเทอร์เฟซตัวฟังข้อความสำหรับถั่วที่ขับเคลื่อนด้วยข้อความ

  • activationConfig - ใช้เพื่อระบุรายละเอียดการกำหนดค่าของถั่วที่ขับเคลื่อนด้วยข้อความในสภาพแวดล้อมการทำงานของถั่วที่ขับเคลื่อนด้วยข้อความ

  • mappedName - ใช้เพื่อระบุชื่อ JNDI ของเซสชั่นบีน

  • description - ใช้เพื่อให้คำอธิบายของเซสชั่นบีน

4

javax.ejb.EJB

ใช้เพื่อระบุหรือฉีดการอ้างอิงเป็นอินสแตนซ์ EJB ลงใน EJB อื่น

Attributes

  • name - ใช้เพื่อระบุชื่อซึ่งจะใช้เพื่อระบุตำแหน่งของถั่วที่อ้างอิงในสภาพแวดล้อม

  • beanInterface - ใช้เพื่อระบุประเภทอินเทอร์เฟซของ bean ที่อ้างอิง

  • beanName - ใช้เพื่อระบุชื่อของถั่วที่อ้างอิง

  • mappedName - ใช้เพื่อระบุชื่อ JNDI ของถั่วที่อ้างอิง

  • description - ใช้เพื่อระบุรายละเอียดของถั่วที่อ้างอิง

5

javax.ejb.Local

ใช้เพื่อระบุอินเตอร์เฟสโลคัลของเซสชั่นบีน อินเทอร์เฟซโลคัลนี้ระบุวิธีการทางธุรกิจของเซสชั่นบีน (ซึ่งอาจเป็นคนไร้สัญชาติหรือสถานะ)

อินเทอร์เฟซนี้ใช้เพื่อแสดงวิธีการทางธุรกิจให้กับไคลเอ็นต์ในพื้นที่ซึ่งรันอยู่ในการปรับใช้ / แอปพลิเคชันเดียวกันกับ EJB

Attributes

  • value - ใช้เพื่อระบุรายการอินเทอร์เฟซภายในเป็นอาร์เรย์ของอินเทอร์เฟซ

6

javax.ejb.Remote

ใช้เพื่อระบุ Remote interface (s) ของ session bean อินเทอร์เฟซระยะไกลนี้ระบุวิธีการทางธุรกิจของเซสชั่นบีน (ซึ่งอาจเป็นสถานะไร้สัญชาติหรือสถานะ)

อินเทอร์เฟซนี้ใช้เพื่อแสดงวิธีการทางธุรกิจกับไคลเอนต์ระยะไกลซึ่งกำลังรันในการปรับใช้ / แอปพลิเคชันที่แตกต่างกันเป็น EJB

Attributes

  • value - ใช้เพื่อระบุรายการของอินเตอร์เฟสระยะไกลเป็นอาร์เรย์ของอินเทอร์เฟซ

7

javax.ejb.Activation ConfigProperty

ใช้เพื่อระบุคุณสมบัติที่ต้องการสำหรับข้อความที่ขับเคลื่อนด้วย bean ตัวอย่างเช่นจุดสิ้นสุดปลายทางตัวเลือกข้อความเป็นต้น

คำอธิบายประกอบนี้ถูกส่งผ่านเป็นพารามิเตอร์ไปยังแอ็ตทริบิวต์ activationConfig ของคำอธิบายประกอบ javax.ejb.MessageDrivenBean

Attributes

  • propertyName - ชื่อทรัพย์สิน

  • propertyValue - มูลค่าทรัพย์สิน

8

javax.ejb.PostActivate

ใช้เพื่อระบุวิธีการโทรกลับของวงจรชีวิต EJB เมธอดนี้จะถูกเรียกใช้เมื่อ EJB container เพิ่งเปิดใช้งาน / เปิดใช้งานอินสแตนซ์ bean อีกครั้ง

อินเทอร์เฟซนี้ใช้เพื่อแสดงวิธีการทางธุรกิจให้กับไคลเอ็นต์ในพื้นที่ซึ่งรันในการปรับใช้ / แอปพลิเคชันเดียวกันกับ EJB

การโทรกลับเป็นกลไกที่สามารถดักจับวงจรชีวิตของเอ็นเตอร์ไพรส์บีนได้ ข้อกำหนด EJB 3.0 ได้ระบุการเรียกกลับสำหรับวิธีการจัดการการโทรกลับที่สร้างขึ้น EJB Container เรียกการเรียกกลับเหล่านี้ เราสามารถกำหนดวิธีการโทรกลับในคลาส EJB เองหรือในคลาสแยกต่างหาก EJB 3.0 ได้จัดเตรียมคำอธิบายประกอบไว้มากมายสำหรับการโทรกลับ

ต่อไปนี้เป็นรายการคำอธิบายประกอบการเรียกกลับสำหรับถั่วไร้สัญชาติ -

คำอธิบายประกอบ คำอธิบาย
@ โพสต์คอนสตรัค เรียกใช้เมื่อถั่วถูกสร้างเป็นครั้งแรก
@PreDestroy เรียกใช้เมื่อ bean ถูกลบออกจาก bean pool หรือถูกทำลาย

ต่อไปนี้เป็นรายการหมายเหตุการเรียกกลับสำหรับ stateful bean -

คำอธิบายประกอบ คำอธิบาย
@ โพสต์คอนสตรัค เรียกใช้เมื่อถั่วถูกสร้างเป็นครั้งแรก
@PreDestroy เรียกใช้เมื่อ bean ถูกลบออกจาก bean pool หรือถูกทำลาย
@PostActivate เรียกใช้เมื่อมีการโหลด bean เพื่อใช้
@PrePassivate เรียกเมื่อ bean ถูกใส่กลับไปที่ bean pool

ต่อไปนี้เป็นรายการคำอธิบายประกอบการติดต่อกลับสำหรับถั่วที่ขับเคลื่อนด้วยข้อความ -

คำอธิบายประกอบ คำอธิบาย
@ โพสต์คอนสตรัค เรียกใช้เมื่อถั่วถูกสร้างเป็นครั้งแรก
@PreDestroy เรียกใช้เมื่อ bean ถูกลบออกจาก bean pool หรือถูกทำลาย

ต่อไปนี้เป็นรายการหมายเหตุประกอบการเรียกกลับสำหรับเอนทิตี bean -

คำอธิบายประกอบ คำอธิบาย
@PrePersist เรียกใช้เมื่อสร้างเอนทิตีในฐานข้อมูล
@PostPersist เรียกใช้หลังจากสร้างเอนทิตีในฐานข้อมูล
@PreRemove เรียกใช้เมื่อเอนทิตีถูกลบออกจากฐานข้อมูล
@PostRemove เรียกใช้หลังจากที่เอนทิตีถูกลบออกจากฐานข้อมูล
@PreUpdate เรียกใช้ก่อนที่จะอัปเดตเอนทิตีในฐานข้อมูล
@PostLoad เรียกใช้เมื่อมีการดึงข้อมูลจากฐานข้อมูลและโหลดลงในเอนทิตี

ตัวอย่างการใช้งาน

ให้เราสร้างแอปพลิเคชั่นทดสอบ EJB เพื่อทดสอบการโทรกลับต่างๆใน EJB

ขั้นตอน คำอธิบาย
1

สร้างโครงการที่มีชื่อEjbComponentภายใต้แพคเกจcom.tutorialspoint.statelessตามที่อธิบายไว้ในEJB - สร้างแอพลิเคชันบท คุณยังสามารถใช้โปรเจ็กต์ที่สร้างในEJB - บทความคงอยู่สำหรับบทนี้เพื่อเพิ่มการเรียกกลับต่างๆไปยัง EJB

2

สร้างLibrarySessionBean.javaและLibrarySessionBeanRemoteตามที่อธิบายไว้ในEJB - สร้างแอพลิเคชันบท เก็บไฟล์ที่เหลือไว้ไม่เปลี่ยนแปลง

3

ใช้ Beans ที่สร้างในบทEJB - Persistence เพิ่มวิธีการโทรกลับตามที่แสดงด้านล่าง เก็บไฟล์ที่เหลือไว้ไม่เปลี่ยนแปลง

4

สร้างคลาส Java BookCallbackListenerภายใต้แพคเกจcom.tutorialspoint.callback คลาสนี้จะสาธิตการแยกวิธีการโทรกลับ

5

ทำความสะอาดและสร้างแอปพลิเคชันเพื่อให้แน่ใจว่าตรรกะทางธุรกิจทำงานได้ตามข้อกำหนด

6

สุดท้ายปรับใช้แอปพลิเคชันในรูปแบบของไฟล์ jar บน JBoss Application Server เซิร์ฟเวอร์แอปพลิเคชัน JBoss จะเริ่มทำงานโดยอัตโนมัติหากยังไม่เริ่มทำงาน

7

ตอนนี้สร้างไคลเอนต์ EJB ซึ่งเป็นแอปพลิเคชันบนคอนโซลในลักษณะเดียวกับที่อธิบายไว้ในบทEJB - Create Applicationภายใต้หัวข้อCreate Client to access EJB.

ส่วนประกอบ EJBC (โมดูล EJB)

BookCallbackListener.java

package com.tutorialspoint.callback;

import javax.persistence.PrePersist;
import javax.persistence.PostLoad;
import javax.persistence.PostPersist;
import javax.persistence.PostRemove;
import javax.persistence.PostUpdate;
import javax.persistence.PreRemove;
import javax.persistence.PreUpdate;

import com.tutorialspoint.entity.Book;

public class BookCallbackListener {
    
   @PrePersist
   public void prePersist(Book book) {
      System.out.println("BookCallbackListener.prePersist:" 
         + "Book to be created with book id: "+book.getId());
   }

   @PostPersist
   public void postPersist(Object book) {
      System.out.println("BookCallbackListener.postPersist::"
         + "Book created with book id: "+((Book)book).getId());
   }

   @PreRemove
   public void preRemove(Book book) {
      System.out.println("BookCallbackListener.preRemove:"
         + " About to delete Book: " + book.getId());
   }

   @PostRemove
   public void postRemove(Book book) {
      System.out.println("BookCallbackListener.postRemove::"
         + " Deleted Book: " + book.getId());
   }

   @PreUpdate
   public void preUpdate(Book book) {
      System.out.println("BookCallbackListener.preUpdate::"
         + " About to update Book: " + book.getId());
   }

   @PostUpdate
   public void postUpdate(Book book) {
      System.out.println("BookCallbackListener.postUpdate::"
         + " Updated Book: " + book.getId());
   }

   @PostLoad
   public void postLoad(Book book) {
      System.out.println("BookCallbackListener.postLoad::"
         + " Loaded Book: " + book.getId());
   }
}

Book.java

package com.tutorialspoint.entity;
 
import java.io.Serializable;

import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.EntityListeners;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.Table;
 
@Entity
@Table(name="books")
public class Book implements Serializable{
    
   private int id;
   private String name;
 
   public Book() {        
   }
 
   @Id
   @GeneratedValue(strategy= GenerationType.IDENTITY)
   @Column(name="id")
   public int getId() {
      return id;
   }
 
   public void setId(int id) {
      this.id = id;
   }
 
   public String getName() {
      return name;
   }
 
   public void setName(String name) {
      this.name = name;
   }    
}

LibraryStatefulSessionBean.java

package com.tutorialspoint.stateful;

import java.util.ArrayList;
import java.util.List;

import javax.annotation.PostConstruct;
import javax.annotation.PreDestroy;

import javax.ejb.PostActivate;
import javax.ejb.PrePassivate;
import javax.ejb.Stateful;

@Stateful
public class LibraryStatefulSessionBean 
   implements LibraryStatefulSessionBeanRemote {
   List<String> bookShelf;    

   public LibraryStatefulSessionBean() {
      bookShelf = new ArrayList<String>();
   }

   public void addBook(String bookName) {
      bookShelf.add(bookName);
   }    

   public List<String> getBooks() {
      return bookShelf;
   }

   @PostConstruct
   public void postConstruct() {
      System.out.println("LibraryStatefulSessionBean.postConstruct::"
         + " bean created.");
   }

   @PreDestroy
   public void preDestroy() {
      System.out.println("LibraryStatefulSessionBean.preDestroy:"
         + " bean removed.");
   }

   @PostActivate
   public void postActivate() {
      System.out.println("LibraryStatefulSessionBean.postActivate:"
         + " bean activated.");
   }

   @PrePassivate
   public void prePassivate() {
      System.out.println("LibraryStatefulSessionBean.prePassivate:"
         + " bean passivated.");
   }    
}

LibraryStatefulSessionBeanRemote.java

package com.tutorialspoint.stateful;

import java.util.List;
import javax.ejb.Remote;

@Remote
public interface LibraryStatefulSessionBeanRemote {
   void addBook(String bookName);
   List getBooks();
}

LibraryPersistentBean.java

package com.tutorialspoint.stateless;

import com.tutorialspoint.entity.Book;
import java.util.List;

import javax.annotation.PostConstruct;
import javax.annotation.PreDestroy;

import javax.ejb.Stateless;
import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;

@Stateless
public class LibraryPersistentBean 
   implements LibraryPersistentBeanRemote {
    
   public LibraryPersistentBean() {}

   @PersistenceContext(unitName="EntityEjbPU")
   private EntityManager entityManager;         

   public void addBook(Book book) {
      entityManager.persist(book);
   }    

   public List<Book> getBooks() {     
      return entityManager.createQuery("From Book")
         .getResultList();
   }

   @PostConstruct
   public void postConstruct() {
      System.out.println("postConstruct:: LibraryPersistentBean session bean"
         + " created with entity Manager object: ");
   }

   @PreDestroy
   public void preDestroy() {
      System.out.println("preDestroy: LibraryPersistentBean session"
      + " bean is removed ");
   }
}

LibraryPersistentBeanRemote.java

package com.tutorialspoint.stateless;

import com.tutorialspoint.entity.Book;
import java.util.List;
import javax.ejb.Remote;

@Remote
public interface LibraryPersistentBeanRemote {

   void addBook(Book bookName);

   List<Book> getBooks();
    
}
  • ทันทีที่คุณปรับใช้โครงการ EjbComponent บน JBOSS ให้สังเกตบันทึก jboss

  • JBoss ได้สร้างรายการ JNDI สำหรับถั่วเซสชันของเราโดยอัตโนมัติ - LibraryPersistentBean/remote.

  • เราจะใช้สตริงการค้นหานี้เพื่อรับวัตถุทางธุรกิจระยะไกลประเภท - com.tutorialspoint.stateless.LibraryPersistentBeanRemote

เอาต์พุตบันทึกของเซิร์ฟเวอร์แอปพลิเคชัน JBoss

...
16:30:01,401 INFO  [JndiSessionRegistrarBase] Binding the following Entries in Global JNDI:
   LibraryPersistentBean/remote - EJB3.x Default Remote Business Interface
   LibraryPersistentBean/remote-com.tutorialspoint.stateless.LibraryPersistentBeanRemote - EJB3.x Remote Business Interface
16:30:02,723 INFO  [SessionSpecContainer] Starting jboss.j2ee:jar=EjbComponent.jar,name=LibraryPersistentBean,service=EJB3
16:30:02,723 INFO  [EJBContainer] STARTED EJB: com.tutorialspoint.stateless.LibrarySessionBeanRemote ejbName: LibraryPersistentBean
...

EJBTester (ไคลเอนต์ EJB)

jndi.properties

java.naming.factory.initial=org.jnp.interfaces.NamingContextFactory
java.naming.factory.url.pkgs=org.jboss.naming:org.jnp.interfaces
java.naming.provider.url=localhost
  • คุณสมบัติเหล่านี้ใช้เพื่อเริ่มต้นอ็อบเจ็กต์ InitialContext ของบริการการตั้งชื่อ java

  • วัตถุ InitialContext จะถูกใช้เพื่อค้นหาเซสชัน bean ที่ไม่มีสถานะ

EJBTester.java

package com.tutorialspoint.test;
   
import com.tutorialspoint.stateful.LibrarySessionBeanRemote;

import java.io.BufferedReader;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStreamReader;

import java.util.List;
import java.util.Properties;

import javax.naming.InitialContext;
import javax.naming.NamingException;

public class EJBTester {

   BufferedReader brConsoleReader = null; 
   Properties props;
   InitialContext ctx;
   {
      props = new Properties();
      try {
         props.load(new FileInputStream("jndi.properties"));
      } catch (IOException ex) {
         ex.printStackTrace();
      }
      try {
         ctx = new InitialContext(props);            
      } catch (NamingException ex) {
         ex.printStackTrace();
      }
      brConsoleReader = 
      new BufferedReader(new InputStreamReader(System.in));
   }
   
   public static void main(String[] args) {

      EJBTester ejbTester = new EJBTester();

      ejbTester.testEntityEjb();
   }
   
   private void showGUI() {
      System.out.println("**********************");
      System.out.println("Welcome to Book Store");
      System.out.println("**********************");
      System.out.print("Options \n1. Add Book\n2. Exit \nEnter Choice: ");
   }
   
   private void testEntityEjb() {    
      try {
      int choice = 1; 

      LibraryPersistentBeanRemote libraryBean = 
      (LibraryPersistentBeanRemote)
      ctx.lookup("LibraryPersistentBean/remote");

      while (choice != 2) {
         String bookName;
         showGUI();
         String strChoice = brConsoleReader.readLine();
         choice = Integer.parseInt(strChoice);
         if (choice == 1) {
            System.out.print("Enter book name: ");
            bookName = brConsoleReader.readLine();
            Book book = new Book();
            book.setName(bookName);
            libraryBean.addBook(book);          
         } else if (choice == 2) {
            break;
         }
      }

      List<Book> booksList = libraryBean.getBooks();

      System.out.println("Book(s) entered so far: " + booksList.size());
      int i = 0;
      for (Book book:booksList) {
         System.out.println((i+1)+". " + book.getName());
         i++;
      }           

      } catch (Exception e) {
         System.out.println(e.getMessage());
         e.printStackTrace();
      }finally {
         try {
            if(brConsoleReader !=null) {
               brConsoleReader.close();
            }
         } catch (IOException ex) {
            System.out.println(ex.getMessage());
         }
      }    
   }    
}

EJBTester ดำเนินการดังต่อไปนี้ -

  • โหลดคุณสมบัติจาก jndi.properties และเริ่มต้นอ็อบเจ็กต์ InitialContext

  • ในเมธอด testStatelessEjb () การค้นหา jndi จะดำเนินการด้วยชื่อ - "LibrarySessionBean / remote" เพื่อรับวัตถุทางธุรกิจระยะไกล (EJB แบบไม่ระบุสถานะ)

  • จากนั้นผู้ใช้จะแสดงส่วนติดต่อผู้ใช้ที่เก็บไลบรารีและระบบจะขอให้ป้อนตัวเลือก

  • หากผู้ใช้ป้อน 1 ระบบจะถามชื่อหนังสือและบันทึกหนังสือโดยใช้วิธี stateless session bean addBook () Session Bean กำลังจัดเก็บหนังสือในฐานข้อมูล

  • หากผู้ใช้ป้อน 2 ระบบจะดึงหนังสือโดยใช้เมธอด getBooks () เซสชัน bean แบบไม่ระบุสถานะและออก

เรียกใช้ไคลเอ็นต์เพื่อเข้าถึง EJB

ค้นหา EJBTester.java ใน project explorer คลิกขวาที่คลาส EJBTester และเลือกrun file.

ตรวจสอบเอาต์พุตต่อไปนี้ในคอนโซล Netbeans

run:
**********************
Welcome to Book Store
**********************
Options 
1. Add Book
2. Exit 
Enter Choice: 1
Enter book name: Learn Java
**********************
Welcome to Book Store
**********************
Options 
1. Add Book
2. Exit 
Enter Choice: 2
Book(s) entered so far: 1
1. Learn Java
BUILD SUCCESSFUL (total time: 13 seconds)

เอาต์พุตบันทึกของเซิร์ฟเวอร์แอปพลิเคชัน JBoss

คุณสามารถค้นหารายการโทรกลับต่อไปนี้ในบันทึก JBoss

14:08:34,293 INFO  [STDOUT] postConstruct:: LibraryPersistentBean session bean created with entity Manager object
...
16:39:09,484 INFO  [STDOUT] BookCallbackListener.prePersist:: Book to be created with book id: 0
16:39:09,531 INFO  [STDOUT] BookCallbackListener.postPersist:: Book created with book id: 1
16:39:09,900 INFO  [STDOUT] BookCallbackListener.postLoad:: Loaded Book: 1
...

Timer Service เป็นกลไกที่สามารถสร้างแอปพลิเคชันตามกำหนดเวลาได้ ตัวอย่างเช่นการสร้างสลิปเงินเดือนในวันที่ 1 ของทุกเดือน ข้อกำหนด EJB 3.0 ได้ระบุคำอธิบายประกอบ @Timeout ซึ่งช่วยในการเขียนโปรแกรมบริการ EJB ในถั่วที่ไม่มีสถานะหรือข้อความ EJB Container เรียกเมธอดซึ่งมีคำอธิบายประกอบโดย @Timeout

EJB Timer Service เป็นบริการที่จัดทำโดย EJB container ซึ่งช่วยในการสร้างตัวจับเวลาและกำหนดเวลาโทรกลับเมื่อหมดเวลา

ขั้นตอนในการสร้างตัวจับเวลา

ใส่ SessionContext ใน bean โดยใช้คำอธิบายประกอบ @Resource -

@Stateless
public class TimerSessionBean {

   @Resource
   private SessionContext context;
   ...
}

ใช้วัตถุ SessionContext เพื่อรับ TimerService และสร้างตัวจับเวลา เวลาผ่านไปเป็นมิลลิวินาทีและข้อความ

public void createTimer(long duration) {
   context.getTimerService().createTimer(duration, "Hello World!");
}

ขั้นตอนในการใช้ตัวตั้งเวลา

ใช้คำอธิบายประกอบ @Timeout กับวิธีการ ประเภทการส่งคืนควรเป็นโมฆะและส่งผ่านพารามิเตอร์ประเภท Timer เรากำลังยกเลิกตัวจับเวลาหลังจากดำเนินการครั้งแรกมิฉะนั้นจะยังคงทำงานต่อไปหลังจากช่วงเวลาแก้ไข

@Timeout
public void timeOutHandler(Timer timer) {
   System.out.println("timeoutHandler : " + timer.getInfo());        
   timer.cancel();
}

ตัวอย่างการใช้งาน

ให้เราสร้างแอปพลิเคชั่นทดสอบ EJB เพื่อทดสอบ Timer Service ใน EJB

ขั้นตอน คำอธิบาย
1

สร้างโครงการที่มีชื่อEjbComponentภายใต้แพคเกจcom.tutorialspoint.timerตามที่อธิบายไว้ในEJB - สร้างแอพลิเคชันบท

2

สร้างTimerSessionBean.javaและTimerSessionBeanRemoteตามที่อธิบายไว้ในEJB - สร้างแอพลิเคชันบท เก็บไฟล์ที่เหลือไว้ไม่เปลี่ยนแปลง

3

ทำความสะอาดและสร้างแอปพลิเคชันเพื่อให้แน่ใจว่าตรรกะทางธุรกิจทำงานได้ตามข้อกำหนด

4

สุดท้ายปรับใช้แอปพลิเคชันในรูปแบบของไฟล์ jar บน JBoss Application Server เซิร์ฟเวอร์แอปพลิเคชัน JBoss จะเริ่มทำงานโดยอัตโนมัติหากยังไม่เริ่มทำงาน

5

ตอนนี้สร้างไคลเอนต์ EJB ซึ่งเป็นแอปพลิเคชันบนคอนโซลในลักษณะเดียวกับที่อธิบายไว้ในบทEJB - Create Applicationภายใต้หัวข้อCreate Client to access EJB.

ส่วนประกอบ EJBC (โมดูล EJB)

TimerSessionBean.java

package com.tutorialspoint.timer;

import javax.annotation.Resource;
import javax.ejb.SessionContext;
import javax.ejb.Timer;
import javax.ejb.Stateless;
import javax.ejb.Timeout;

@Stateless
public class TimerSessionBean implements TimerSessionBeanRemote {

   @Resource
   private SessionContext context;

   public void createTimer(long duration) {
      context.getTimerService().createTimer(duration, "Hello World!");
   }

   @Timeout
   public void timeOutHandler(Timer timer) {
      System.out.println("timeoutHandler : " + timer.getInfo());        
      timer.cancel();
   }
}

TimerSessionBeanRemote.java

package com.tutorialspoint.timer;

import javax.ejb.Remote;

@Remote
public interface TimerSessionBeanRemote {
   public void createTimer(long milliseconds);
}
  • ทันทีที่คุณปรับใช้โครงการ EjbComponent บน JBOSS ให้สังเกตบันทึก jboss

  • JBoss ได้สร้างรายการ JNDI สำหรับถั่วเซสชันของเราโดยอัตโนมัติ - TimerSessionBean/remote.

  • เราจะใช้สตริงการค้นหานี้เพื่อรับวัตถุทางธุรกิจระยะไกลประเภท - com.tutorialspoint.timer.TimerSessionBeanRemote

เอาต์พุตบันทึกของเซิร์ฟเวอร์แอปพลิเคชัน JBoss

...
16:30:01,401 INFO  [JndiSessionRegistrarBase] Binding the following Entries in Global JNDI:
   TimerSessionBean/remote - EJB3.x Default Remote Business Interface
   TimerSessionBean/remote-com.tutorialspoint.timer.TimerSessionBeanRemote - EJB3.x Remote Business Interface
16:30:02,723 INFO  [SessionSpecContainer] Starting jboss.j2ee:jar=EjbComponent.jar,name=TimerSessionBean,service=EJB3
16:30:02,723 INFO  [EJBContainer] STARTED EJB: com.tutorialspoint.timer.TimerSessionBeanRemote ejbName: TimerSessionBean
...

EJBTester (ไคลเอนต์ EJB)

jndi.properties

java.naming.factory.initial=org.jnp.interfaces.NamingContextFactory
java.naming.factory.url.pkgs=org.jboss.naming:org.jnp.interfaces
java.naming.provider.url=localhost
  • คุณสมบัติเหล่านี้ใช้เพื่อเริ่มต้นอ็อบเจ็กต์ InitialContext ของบริการการตั้งชื่อ java

  • วัตถุ InitialContext จะถูกใช้เพื่อค้นหาเซสชัน bean ที่ไม่มีสถานะ

EJBTester.java

package com.tutorialspoint.test;
   
import com.tutorialspoint.stateful.TimerSessionBeanRemote;
import java.io.BufferedReader;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.List;
import java.util.Properties;
import javax.naming.InitialContext;
import javax.naming.NamingException;

public class EJBTester {

   BufferedReader brConsoleReader = null; 
   Properties props;
   InitialContext ctx;
   {
      props = new Properties();
      try {
         props.load(new FileInputStream("jndi.properties"));
      } catch (IOException ex) {
         ex.printStackTrace();
      }
      try {
         ctx = new InitialContext(props);            
      } catch (NamingException ex) {
         ex.printStackTrace();
      }
      brConsoleReader = 
      new BufferedReader(new InputStreamReader(System.in));
   }
   
   public static void main(String[] args) {

      EJBTester ejbTester = new EJBTester();

      ejbTester.testTimerService();
   }
   
   private void showGUI() {
      System.out.println("**********************");
      System.out.println("Welcome to Book Store");
      System.out.println("**********************");
      System.out.print("Options \n1. Add Book\n2. Exit \nEnter Choice: ");
   }
   
   private void testTimerService() {
      try {
         TimerSessionBeanRemote timerServiceBean = (TimerSessionBeanRemote)ctx.lookup("TimerSessionBean/remote");

         System.out.println("["+(new Date()).toString()+ "]" + "timer created.");
         timerServiceBean.createTimer(2000);            

      } catch (NamingException ex) {
         ex.printStackTrace();
      }
   }
}

EJBTester กำลังทำงานต่อไปนี้

  • โหลดคุณสมบัติจาก jndi.properties และเริ่มต้นอ็อบเจ็กต์ InitialContext

  • ในเมธอด testTimerService () การค้นหา jndi จะดำเนินการด้วยชื่อ - "TimerSessionBean / remote" เพื่อรับวัตถุทางธุรกิจระยะไกล (timer stateless EJB)

  • จากนั้นจะเรียก createTimer ผ่าน 2,000 มิลลิวินาทีเป็นเวลาตามกำหนดการ

  • EJB Container เรียกเมธอด timeoutHandler หลังจาก 2 วินาที

เรียกใช้ไคลเอ็นต์เพื่อเข้าถึง EJB

ค้นหา EJBTester.java ใน project explorer คลิกขวาที่คลาส EJBTester และเลือกrun file.

ตรวจสอบเอาต์พุตต่อไปนี้ในคอนโซล Netbeans

run:
[Wed Jun 19 11:35:47 IST 2013]timer created.
BUILD SUCCESSFUL (total time: 0 seconds)

เอาต์พุตบันทึกของเซิร์ฟเวอร์แอปพลิเคชัน JBoss

คุณสามารถค้นหารายการโทรกลับต่อไปนี้ในบันทึก JBoss

...
11:35:49,555 INFO  [STDOUT] timeoutHandler : Hello World!
...

ข้อกำหนด EJB 3.0 จัดเตรียมคำอธิบายประกอบซึ่งสามารถใช้กับฟิลด์หรือวิธีการ setter เพื่อแทรกการอ้างอิง EJB Container ใช้รีจิสทรี JNDI ส่วนกลางเพื่อค้นหาการอ้างอิง คำอธิบายประกอบต่อไปนี้ใช้ใน EJB 3.0 สำหรับการฉีดแบบพึ่งพา

  • @EJB - ใช้เพื่อฉีดข้อมูลอ้างอิง EJB อื่น ๆ

  • @Resource - ใช้ในการฉีดแหล่งข้อมูลหรือบริการเดี่ยวเช่น sessionContext, timerService เป็นต้น

ขั้นตอนการใช้งาน @EJB

@EJB สามารถใช้กับฟิลด์หรือวิธีการในลักษณะต่อไปนี้ -

public class LibraryMessageBean implements MessageListener {
   //dependency injection on field. 
   @EJB
   LibraryPersistentBeanRemote libraryBean;
   ...
}
public class LibraryMessageBean implements MessageListener {
  
   LibraryPersistentBeanRemote libraryBean;
   
   //dependency injection on method. 
   @EJB(beanName="com.tutorialspoint.stateless.LibraryPersistentBean")
   public void setLibraryPersistentBean(
   LibraryPersistentBeanRemote libraryBean)
   {
      this.libraryBean = libraryBean;
   }
   ...
}

ขั้นตอนในการใช้ @Resource

โดยปกติจะใช้ @Resource เพื่อฉีด EJB Container ที่ให้มา

public class LibraryMessageBean implements MessageListener {
   @Resource
   private MessageDrivenContext mdctx;  
   ...
}

ตัวอย่างการใช้งาน

ให้เราสร้างแอปพลิเคชันทดสอบ EJB เพื่อทดสอบ Dependency Injection Service ใน EJB

ขั้นตอน คำอธิบาย
1

สร้างโครงการที่มีชื่อEjbComponentภายใต้แพคเกจcom.tutorialspoint.timerตามที่อธิบายไว้ในEJB - สร้างแอพลิเคชันบท

2

ใช้ถั่วสร้างขึ้นในEJB - ข้อความ Driven Beanบท เก็บไฟล์ที่เหลือไว้ไม่เปลี่ยนแปลง

3

ทำความสะอาดและสร้างแอปพลิเคชันเพื่อให้แน่ใจว่าตรรกะทางธุรกิจทำงานได้ตามข้อกำหนด

4

สุดท้ายปรับใช้แอปพลิเคชันในรูปแบบของไฟล์ jar บน JBoss Application Server เซิร์ฟเวอร์แอปพลิเคชัน JBoss จะเริ่มทำงานโดยอัตโนมัติหากยังไม่เริ่มทำงาน

5

ตอนนี้สร้างไคลเอนต์ EJB ซึ่งเป็นแอปพลิเคชันบนคอนโซลในลักษณะเดียวกับที่อธิบายไว้ในบทEJB - Create Applicationภายใต้หัวข้อCreate Client to access EJB.

ส่วนประกอบ EJBC (โมดูล EJB)

LibraryMessageBean.java

package com.tuturialspoint.messagebean;
 
import com.tutorialspoint.entity.Book;
import com.tutorialspoint.stateless.LibraryPersistentBeanRemote;
import javax.annotation.Resource;
import javax.ejb.ActivationConfigProperty;
import javax.ejb.EJB;
import javax.ejb.MessageDriven;
import javax.ejb.MessageDrivenContext;
import javax.jms.JMSException;
import javax.jms.Message;
import javax.jms.MessageListener;
import javax.jms.ObjectMessage;
 
@MessageDriven(
   name = "BookMessageHandler",
   activationConfig = {
      @ActivationConfigProperty( propertyName = "destinationType", 
                                 propertyValue = "javax.jms.Queue"),
      @ActivationConfigProperty( propertyName = "destination", 
                                 propertyValue ="/queue/BookQueue")
   }
)
public class LibraryMessageBean implements MessageListener {
 
   @Resource
   private MessageDrivenContext mdctx;  
 
   @EJB
   LibraryPersistentBeanRemote libraryBean;
 
   public LibraryMessageBean() {        
   }
 
   public void onMessage(Message message) {
      ObjectMessage objectMessage = null;
      try {
         objectMessage = (ObjectMessage) message;
         Book book = (Book) objectMessage.getObject(); 
         libraryBean.addBook(book);
 
      }catch (JMSException ex) {
         mdctx.setRollbackOnly();
      }       
   }   
}

EJBTester (ไคลเอนต์ EJB)

EJBTester.java

package com.tutorialspoint.test;
   
import com.tutorialspoint.entity.Book;
import com.tutorialspoint.stateless.LibraryPersistentBeanRemote;
import java.io.BufferedReader;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.List;
import java.util.Properties;
import javax.jms.ObjectMessage;
import javax.jms.Queue;
import javax.jms.QueueConnection;
import javax.jms.QueueConnectionFactory;
import javax.jms.QueueSender;
import javax.jms.QueueSession;
import javax.naming.InitialContext;
import javax.naming.NamingException;
 
public class EJBTester {
 
   BufferedReader brConsoleReader = null; 
   Properties props;
   InitialContext ctx;
   {
      props = new Properties();
      try {
         props.load(new FileInputStream("jndi.properties"));
      } catch (IOException ex) {
         ex.printStackTrace();
      }
      try {
         ctx = new InitialContext(props);            
      } catch (NamingException ex) {
         ex.printStackTrace();
      }
      brConsoleReader = 
      new BufferedReader(new InputStreamReader(System.in));
   }
   
   public static void main(String[] args) {
 
      EJBTester ejbTester = new EJBTester();
 
      ejbTester.testMessageBeanEjb();
   }
   
   private void showGUI() {
      System.out.println("**********************");
      System.out.println("Welcome to Book Store");
      System.out.println("**********************");
      System.out.print("Options \n1. Add Book\n2. Exit \nEnter Choice: ");
   }
   
   private void testMessageBeanEjb() {
 
      try {
         int choice = 1; 
         Queue queue = (Queue) ctx.lookup("/queue/BookQueue");
         QueueConnectionFactory factory =
         (QueueConnectionFactory) ctx.lookup("ConnectionFactory");
         QueueConnection connection =  factory.createQueueConnection();
         QueueSession session = connection.createQueueSession( 
         false, QueueSession.AUTO_ACKNOWLEDGE);
         QueueSender sender = session.createSender(queue);
 
         while (choice != 2) {
            String bookName;
            showGUI();
            String strChoice = brConsoleReader.readLine();
            choice = Integer.parseInt(strChoice);
            if (choice == 1) {
               System.out.print("Enter book name: ");
               bookName = brConsoleReader.readLine();
               Book book = new Book();
               book.setName(bookName);
               ObjectMessage objectMessage = 
               session.createObjectMessage(book);
               sender.send(objectMessage); 
            } else if (choice == 2) {
               break;
            }
         }
 
         LibraryPersistentBeanRemote libraryBean = 
         (LibraryPersistentBeanRemote)
		 ctx.lookup("LibraryPersistentBean/remote");
 
         List<Book> booksList = libraryBean.getBooks();
 
         System.out.println("Book(s) entered so far: " 
         + booksList.size());
         int i = 0;
         for (Book book:booksList) {
            System.out.println((i+1)+". " + book.getName());
            i++;
         }           
      } catch (Exception e) {
         System.out.println(e.getMessage());
         e.printStackTrace();
      }finally {
         try {
            if(brConsoleReader !=null) {
               brConsoleReader.close();
            }
         } catch (IOException ex) {
            System.out.println(ex.getMessage());
         }
      }
   }   
}

EJBTester ดำเนินการดังต่อไปนี้ -

  • โหลดคุณสมบัติจาก jndi.properties และเริ่มต้นอ็อบเจ็กต์ InitialContext

  • ในเมธอด testStatefulEjb () การค้นหา jndi จะดำเนินการด้วยชื่อ - "/ que / BookQueue" เพื่อขอรับการอ้างอิงของคิวที่มีอยู่ใน Jboss จากนั้นผู้ส่งจะถูกสร้างขึ้นโดยใช้เซสชันคิว

  • จากนั้นผู้ใช้จะแสดงส่วนติดต่อผู้ใช้ที่เก็บไลบรารีและระบบจะขอให้ผู้ใช้ป้อนตัวเลือก

  • หากผู้ใช้ป้อน 1 ระบบจะถามชื่อหนังสือและผู้ส่งจะส่งชื่อหนังสือเข้าคิว เมื่อคอนเทนเนอร์ JBoss ได้รับข้อความนี้ในคิวจะเรียกใช้เมธอด onMessage ของถั่วที่ขับเคลื่อนด้วยข้อความ ข้อความของเราที่ขับเคลื่อนด้วย bean จะบันทึกหนังสือโดยใช้วิธี stateful session bean addBook () Session Bean ยังคงมีหนังสืออยู่ในฐานข้อมูลผ่านการเรียก EntityManager

  • หากผู้ใช้ป้อน 2 จะมีการค้นหา jndi อีกครั้งด้วยชื่อ - "LibraryStatefulSessionBean / remote" เพื่อรับวัตถุทางธุรกิจระยะไกล (stateful EJB) อีกครั้งและทำรายการหนังสือ

เรียกใช้ไคลเอ็นต์เพื่อเข้าถึง EJB

ค้นหา EJBTester.java ใน project explorer คลิกขวาที่คลาส EJBTester และเลือกrun file.

ตรวจสอบเอาต์พุตต่อไปนี้ในคอนโซล Netbeans

run:
**********************
Welcome to Book Store
**********************
Options 
1. Add Book
2. Exit 
Enter Choice: 1
Enter book name: Learn EJB
**********************
Welcome to Book Store
**********************
Options 
1. Add Book
2. Exit 
Enter Choice: 2
Book(s) entered so far: 2
1. learn java
1. learn EJB
BUILD SUCCESSFUL (total time: 15 seconds)

ผลลัพธ์ที่แสดงด้านบนระบุว่า Message driven bean ของเราได้รับข้อความและจัดเก็บหนังสือในที่จัดเก็บถาวรและหนังสือจะถูกดึงมาจากฐานข้อมูล

ถั่วที่ขับเคลื่อนด้วยข้อความของเรากำลังใช้ LibraryPersistentBean ที่แทรกเข้าไปโดยใช้คำอธิบายประกอบ @EJB และในกรณีที่มีข้อยกเว้น MessageDrivenContext อ็อบเจ็กต์จะถูกใช้เพื่อย้อนกลับธุรกรรม

EJB 3.0 ให้ข้อกำหนดในการสกัดกั้นการเรียกวิธีการทางธุรกิจโดยใช้วิธีการที่มีคำอธิบายประกอบ @AroundInvoke วิธีการดักจับถูกเรียกโดย ejbContainer ก่อนที่วิธีการทางธุรกิจจะเรียกมันว่าการสกัดกั้น ต่อไปนี้เป็นตัวอย่างลายเซ็นของวิธีการสกัดกั้น

@AroundInvoke
public Object methodInterceptor(InvocationContext ctx) throws Exception {
   System.out.println("*** Intercepting call to LibraryBean method: " 
   + ctx.getMethod().getName());
   return ctx.proceed();
}

วิธีการสกัดกั้นสามารถใช้หรือผูกมัดได้ในสามระดับ

  • Default - ตัวสกัดเริ่มต้นถูกเรียกใช้สำหรับทุก bean ภายในการปรับใช้ตัวสกัดกั้นเริ่มต้นสามารถใช้ได้ผ่าน xml เท่านั้น (ejb-jar.xml)

  • Class- ตัวสกัดกั้นระดับคลาสถูกเรียกใช้สำหรับทุกวิธีของถั่ว ตัวสกัดกั้นระดับคลาสสามารถใช้ได้ทั้งโดยการใส่คำอธิบายประกอบผ่าน xml (ejb-jar.xml)

  • Method- ตัวสกัดกั้นระดับวิธีถูกเรียกใช้สำหรับวิธีการเฉพาะของถั่ว ตัวสกัดกั้นระดับวิธีสามารถใช้ได้ทั้งโดยการใส่คำอธิบายประกอบผ่าน xml (ejb-jar.xml)

เรากำลังพูดถึงผู้สกัดกั้นระดับคลาสที่นี่

คลาส Interceptor

package com.tutorialspoint.interceptor;

import javax.interceptor.AroundInvoke;
import javax.interceptor.InvocationContext;

public class BusinessInterceptor {
   @AroundInvoke
   public Object methodInterceptor(InvocationContext ctx) throws Exception {
      System.out.println("*** Intercepting call to LibraryBean method: " 
      + ctx.getMethod().getName());
      return ctx.proceed();
   }
}

อินเทอร์เฟซระยะไกล

import javax.ejb.Remote;

@Remote
public interface LibraryBeanRemote {
   //add business method declarations
}

สกัดกั้น EJB ไร้สัญชาติ

@Interceptors ({BusinessInterceptor.class})
@Stateless
public class LibraryBean implements LibraryBeanRemote {
   //implement business method 
}

ตัวอย่างการใช้งาน

ให้เราสร้างแอปพลิเคชันทดสอบ EJB เพื่อทดสอบ EJB ไร้สัญชาติที่ถูกดักฟัง

ขั้นตอน คำอธิบาย
1

สร้างโครงการที่มีชื่อEjbComponentภายใต้แพคเกจcom.tutorialspoint.interceptorตามที่อธิบายไว้ในEJB - สร้างแอพลิเคชันบท คุณยังสามารถใช้โครงการที่สร้างในEJB - สร้างบทแอปพลิเคชันสำหรับบทนี้เพื่อทำความเข้าใจแนวคิด EJB ที่ถูกดักฟัง

2

สร้างLibraryBean.javaและLibraryBeanRemoteภายใต้แพคเกจcom.tutorialspoint.interceptorตามที่อธิบายไว้ในEJB - สร้างแอพลิเคชันบท เก็บไฟล์ที่เหลือไว้ไม่เปลี่ยนแปลง

3

ทำความสะอาดและสร้างแอปพลิเคชันเพื่อให้แน่ใจว่าตรรกะทางธุรกิจทำงานได้ตามข้อกำหนด

4

สุดท้ายปรับใช้แอปพลิเคชันในรูปแบบของไฟล์ jar บน JBoss Application Server เซิร์ฟเวอร์แอปพลิเคชัน JBoss จะเริ่มทำงานโดยอัตโนมัติหากยังไม่เริ่มทำงาน

5

ตอนนี้สร้างไคลเอนต์ ejb ซึ่งเป็นแอปพลิเคชันที่ใช้คอนโซลในลักษณะเดียวกับที่อธิบายไว้ในบทEJB - Create Applicationภายใต้หัวข้อCreate Client to access EJB.

ส่วนประกอบ EJBC (โมดูล EJB)

LibraryBeanRemote.java

package com.tutorialspoint.interceptor;

import java.util.List;
import javax.ejb.Remote;

@Remote
public interface LibraryBeanRemote {
   void addBook(String bookName);
   List getBooks();
}

LibraryBean.java

package com.tutorialspoint.interceptor;

import java.util.ArrayList;
import java.util.List;

import javax.ejb.Stateless;
import javax.interceptor.Interceptors;

@Interceptors ({BusinessInterceptor.class})
@Stateless
public class LibraryBean implements LibraryBeanRemote {
    
   List<String> bookShelf;    

   public LibraryBean() {
      bookShelf = new ArrayList<String>();
   }

   public void addBook(String bookName) {
      bookShelf.add(bookName);
   }    

   public List<String> getBooks() {
      return bookShelf;
   }   
}
  • ทันทีที่คุณปรับใช้โครงการ EjbComponent บน JBOSS ให้สังเกตบันทึก jboss

  • JBoss ได้สร้างรายการ JNDI สำหรับถั่วเซสชันของเราโดยอัตโนมัติ - LibraryBean/remote.

  • เราจะใช้สตริงการค้นหานี้เพื่อรับวัตถุทางธุรกิจระยะไกลประเภท - com.tutorialspoint.interceptor.LibraryBeanRemote

เอาต์พุตบันทึกของเซิร์ฟเวอร์แอปพลิเคชัน JBoss

...
16:30:01,401 INFO  [JndiSessionRegistrarBase] Binding the following Entries in Global JNDI:
   LibraryBean/remote - EJB3.x Default Remote Business Interface
   LibraryBean/remote-com.tutorialspoint.interceptor.LibraryBeanRemote - EJB3.x Remote Business Interface
16:30:02,723 INFO  [SessionSpecContainer] Starting jboss.j2ee:jar=EjbComponent.jar,name=LibraryBean,service=EJB3
16:30:02,723 INFO  [EJBContainer] STARTED EJB: com.tutorialspoint.interceptor.LibraryBeanRemote ejbName: LibraryBean
16:30:02,731 INFO  [JndiSessionRegistrarBase] Binding the following Entries in Global JNDI:

   LibraryBean/remote - EJB3.x Default Remote Business Interface
   LibraryBean/remote-com.tutorialspoint.interceptor.LibraryBeanRemote - EJB3.x Remote Business Interface
...

EJBTester (ไคลเอนต์ EJB)

jndi.properties

java.naming.factory.initial=org.jnp.interfaces.NamingContextFactory
java.naming.factory.url.pkgs=org.jboss.naming:org.jnp.interfaces
java.naming.provider.url=localhost
  • คุณสมบัติเหล่านี้ใช้เพื่อเริ่มต้นอ็อบเจ็กต์ InitialContext ของบริการการตั้งชื่อ java

  • วัตถุ InitialContext จะถูกใช้เพื่อค้นหาเซสชัน bean ที่ไม่มีสถานะ

EJBTester.java

package com.tutorialspoint.test;
   
import com.tutorialspoint.stateful.LibraryBeanRemote;

import java.io.BufferedReader;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStreamReader;

import java.util.List;
import java.util.Properties;

import javax.naming.InitialContext;
import javax.naming.NamingException;

public class EJBTester {

   BufferedReader brConsoleReader = null; 
   Properties props;
   InitialContext ctx;
   {
      props = new Properties();
      try {
         props.load(new FileInputStream("jndi.properties"));
      } catch (IOException ex) {
         ex.printStackTrace();
      }
      try {
         ctx = new InitialContext(props);            
      } catch (NamingException ex) {
         ex.printStackTrace();
      }
      brConsoleReader = 
      new BufferedReader(new InputStreamReader(System.in));
   }
   
   public static void main(String[] args) {

      EJBTester ejbTester = new EJBTester();

      ejbTester.testInterceptedEjb();
   }
   
   private void showGUI() {
      System.out.println("**********************");
      System.out.println("Welcome to Book Store");
      System.out.println("**********************");
      System.out.print("Options \n1. Add Book\n2. Exit \nEnter Choice: ");
   }
   
   private void testInterceptedEjb() {

      try {
         int choice = 1; 

         LibraryBeanRemote libraryBean =
         LibraryBeanRemote)ctx.lookup("LibraryBean/remote");

         while (choice != 2) {
            String bookName;
            showGUI();
            String strChoice = brConsoleReader.readLine();
            choice = Integer.parseInt(strChoice);
            if (choice == 1) {
               System.out.print("Enter book name: ");
               bookName = brConsoleReader.readLine();
               Book book = new Book();
               book.setName(bookName);
               libraryBean.addBook(book);          
            } else if (choice == 2) {
               break;
            }
         }

         List<Book> booksList = libraryBean.getBooks();

         System.out.println("Book(s) entered so far: " + booksList.size());
         int i = 0;
         for (Book book:booksList) {
            System.out.println((i+1)+". " + book.getName());
            i++;
         }                
      } catch (Exception e) {
         System.out.println(e.getMessage());
         e.printStackTrace();
      }finally {
         try {
            if(brConsoleReader !=null) {
               brConsoleReader.close();
            }
         } catch (IOException ex) {
            System.out.println(ex.getMessage());
         }
      }
   }
}

EJBTester ดำเนินการดังต่อไปนี้ -

  • โหลดคุณสมบัติจาก jndi.properties และเริ่มต้นอ็อบเจ็กต์ InitialContext

  • ในเมธอด testInterceptedEjb () การค้นหา jndi จะดำเนินการด้วยชื่อ - "LibraryBean / remote" เพื่อรับอ็อบเจ็กต์ธุรกิจระยะไกล (EJB ไร้สถานะ)

  • จากนั้นผู้ใช้จะแสดงส่วนติดต่อผู้ใช้ที่เก็บไลบรารีและระบบจะขอให้ป้อนตัวเลือก

  • หากผู้ใช้ป้อน 1 ระบบจะถามชื่อหนังสือและบันทึกหนังสือโดยใช้วิธี stateless session bean addBook () Session Bean กำลังจัดเก็บหนังสือในตัวแปรอินสแตนซ์

  • หากผู้ใช้ป้อน 2 ระบบจะดึงหนังสือโดยใช้เมธอด stateless session bean getBooks () และออก

เรียกใช้ไคลเอ็นต์เพื่อเข้าถึง EJB

ค้นหา EJBTester.java ใน project explorer คลิกขวาที่คลาส EJBTester และเลือกrun file.

ตรวจสอบเอาต์พุตต่อไปนี้ในคอนโซล Netbeans

run:
**********************
Welcome to Book Store
**********************
Options 
1. Add Book
2. Exit 
Enter Choice: 1
Enter book name: Learn Java
**********************
Welcome to Book Store
**********************
Options 
1. Add Book
2. Exit 
Enter Choice: 2
Book(s) entered so far: 1
1. Learn Java
BUILD SUCCESSFUL (total time: 13 seconds)

เอาต์พุตบันทึกของเซิร์ฟเวอร์แอปพลิเคชัน JBoss

ตรวจสอบเอาต์พุตต่อไปนี้ในเอาต์พุตบันทึกของเซิร์ฟเวอร์ JBoss Application

....
09:55:40,741 INFO  [STDOUT] *** Intercepting call to LibraryBean method: addBook
09:55:43,661 INFO  [STDOUT] *** Intercepting call to LibraryBean method: getBooks

EJB 3.0 มีอ็อพชันในการฝัง JAVA POJO (Plain Old Java Object) ลงในเอนทิตี bean และอนุญาตให้แม็พชื่อคอลัมน์ด้วยเมธอดของคลาส POJO ที่ฝังไว้ java POJO ที่จะฝังต้องมีคำอธิบายประกอบเป็น @Embeddable

@Embeddable
public class Publisher implements Serializable{
   private String name;
   private String address;
   ...
}

สามารถฝังคลาสข้างต้นได้โดยใช้คำอธิบายประกอบ @Embedded

@Entity
public class Book implements Serializable{
   private int id;
   private String name;
   private Publisher publisher;
   ...
   @Embedded
   @AttributeOverrides({
      @AttributeOverride(name = "name", 
                      column = @Column(name = "PUBLISHER")),
      @AttributeOverride(name = "address", 
                      column = @Column(name = "PUBLISHER_ADDRESS"))
   })
   public Publisher getPublisher() {
      return publisher;
   }
   ...
}

ตัวอย่างการใช้งาน

ให้เราสร้างแอปพลิเคชันทดสอบ EJB เพื่อทดสอบวัตถุฝังตัวใน EJB 3.0

ขั้นตอน คำอธิบาย
1

สร้างโครงการที่มีชื่อEjbComponentภายใต้แพคเกจcom.tutorialspoint.entityตามที่อธิบายไว้ในEJB - สร้างแอพลิเคชันบท โปรดใช้โปรเจ็กต์ที่สร้างขึ้นในEJB - บทความคงอยู่สำหรับบทนี้เพื่อทำความเข้าใจอ็อบเจ็กต์ฝังตัวในแนวคิด EJB

2

สร้างPublisher.javaภายใต้แพคเกจcom.tutorialspoint.entityตามที่อธิบายไว้ในEJB - สร้างแอพลิเคชันบท เก็บไฟล์ที่เหลือไว้ไม่เปลี่ยนแปลง

3

สร้างBook.javaภายใต้แพคเกจcom.tutorialspoint.entity ใช้EJB - บทความคงทนเป็นข้อมูลอ้างอิง เก็บไฟล์ที่เหลือไว้ไม่เปลี่ยนแปลง

4

ทำความสะอาดและสร้างแอปพลิเคชันเพื่อให้แน่ใจว่าตรรกะทางธุรกิจทำงานได้ตามข้อกำหนด

5

สุดท้ายปรับใช้แอปพลิเคชันในรูปแบบของไฟล์ jar บน JBoss Application Server เซิร์ฟเวอร์แอปพลิเคชัน JBoss จะเริ่มทำงานโดยอัตโนมัติหากยังไม่เริ่มทำงาน

6

ตอนนี้สร้างไคลเอนต์ EJB ซึ่งเป็นแอปพลิเคชันบนคอนโซลในลักษณะเดียวกับที่อธิบายไว้ในบทEJB - Create Applicationภายใต้หัวข้อCreate Client to access EJB.

สร้าง / แก้ไขตารางหนังสือ

CREATE TABLE book (
   id     integer PRIMARY KEY,
   name   varchar(50)
);
Alter table book add publisher varchar(100);
Alter table book add publisher_address varchar(200);

ส่วนประกอบ EJBC (โมดูล EJB)

Publisher.java

package com.tutorialspoint.entity;

import java.io.Serializable;
import javax.persistence.Embeddable;

@Embeddable
public class Publisher implements Serializable{
    
   private String name;
   private String address;

   public Publisher() {}

   public Publisher(String name, String address) {
      this.name = name;
      this.address = address;
   }

   public String getName() {
      return name;
   }

   public void setName(String name) {
      this.name = name;
   }

   public String getAddress() {
      return address;
   }

   public void setAddress(String address) {
      this.address = address;
   }

   public String toString() {
      return name + "," + address;
   }    
}

Book.java

package com.tutorialspoint.entity;

import com.tutorialspoint.callback.BookCallbackListener;
import java.io.Serializable;

import javax.persistence.AttributeOverride;
import javax.persistence.AttributeOverrides;
import javax.persistence.Column;
import javax.persistence.Embedded;
import javax.persistence.Entity;
import javax.persistence.EntityListeners;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.Table;

@Entity
@Table(name="book")
public class Book implements Serializable{

   private int id;
   private String name;
   private Publisher publisher;

   public Book() {        
   }

   @Id
   @GeneratedValue(strategy= GenerationType.IDENTITY)
   @Column(name="id")
   public int getId() {
      return id;
   }

   public void setId(int id) {
      this.id = id;
   }

   public String getName() {
      return name;
   }

   public void setName(String name) {
      this.name = name;
   }


   @Embedded
   @AttributeOverrides({
      @AttributeOverride(name = "name", 
         column = @Column(name = "PUBLISHER")),
      @AttributeOverride(name = "address", 
         column = @Column(name = "PUBLISHER_ADDRESS"))
   })
   public Publisher getPublisher() {
      return publisher;
   }

   public void setPublisher(Publisher publisher) {
      this.publisher = publisher;
   }    
}

LibraryPersistentBeanRemote.java

package com.tutorialspoint.stateless;

import com.tutorialspoint.entity.Book;
import java.util.List;
import javax.ejb.Remote;

@Remote
public interface LibraryPersistentBeanRemote {

   void addBook(Book bookName);

   List<Book> getBooks();
    
}

LibraryPersistentBean.java

package com.tutorialspoint.stateless;

import com.tutorialspoint.entity.Book;
import java.util.List;
import javax.ejb.Stateless;

import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;

@Stateless
public class LibraryPersistentBean implements LibraryPersistentBeanRemote {
    
   public LibraryPersistentBean() {
   }

   @PersistenceContext(unitName="EjbComponentPU")
   private EntityManager entityManager;         

   public void addBook(Book book) {
      entityManager.persist(book);
   }    

   public List<Book> getBooks() {
      return entityManager.createQuery("From Book").getResultList();
   }
}
  • ทันทีที่คุณปรับใช้โครงการ EjbComponent บน JBOSS ให้สังเกตบันทึก jboss

  • JBoss ได้สร้างรายการ JNDI สำหรับถั่วเซสชันของเราโดยอัตโนมัติ - LibraryPersistentBean/remote.

  • เราจะใช้สตริงการค้นหานี้เพื่อรับวัตถุทางธุรกิจระยะไกลประเภท - com.tutorialspoint.interceptor.LibraryPersistentBeanRemote

เอาต์พุตบันทึกของเซิร์ฟเวอร์แอปพลิเคชัน JBoss

...
16:30:01,401 INFO  [JndiSessionRegistrarBase] Binding the following Entries in Global JNDI:
   LibraryPersistentBean/remote - EJB3.x Default Remote Business Interface
   LibraryPersistentBean/remote-com.tutorialspoint.interceptor.LibraryPersistentBeanRemote - EJB3.x Remote Business Interface
16:30:02,723 INFO  [SessionSpecContainer] Starting jboss.j2ee:jar=EjbComponent.jar,name=LibraryPersistentBean,service=EJB3
16:30:02,723 INFO  [EJBContainer] STARTED EJB: com.tutorialspoint.interceptor.LibraryPersistentBeanRemote ejbName: LibraryPersistentBean
16:30:02,731 INFO  [JndiSessionRegistrarBase] Binding the following Entries in Global JNDI:

   LibraryPersistentBean/remote - EJB3.x Default Remote Business Interface
   LibraryPersistentBean/remote-com.tutorialspoint.interceptor.LibraryPersistentBeanRemote - EJB3.x Remote Business Interface
...

EJBTester (ไคลเอนต์ EJB)

jndi.properties

java.naming.factory.initial=org.jnp.interfaces.NamingContextFactory
java.naming.factory.url.pkgs=org.jboss.naming:org.jnp.interfaces
java.naming.provider.url=localhost
  • คุณสมบัติเหล่านี้ใช้เพื่อเริ่มต้นอ็อบเจ็กต์ InitialContext ของบริการการตั้งชื่อ java

  • วัตถุ InitialContext จะถูกใช้เพื่อค้นหาเซสชัน bean ที่ไม่มีสถานะ

EJBTester.java

package com.tutorialspoint.test;
   
import com.tutorialspoint.stateful.LibraryBeanRemote;

import java.io.BufferedReader;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStreamReader;

import java.util.List;
import java.util.Properties;

import javax.naming.InitialContext;
import javax.naming.NamingException;

public class EJBTester {

   BufferedReader brConsoleReader = null; 
   Properties props;
   InitialContext ctx;
   {
      props = new Properties();
      try {
         props.load(new FileInputStream("jndi.properties"));
      } catch (IOException ex) {
         ex.printStackTrace();
      }
      try {
         ctx = new InitialContext(props);            
      } catch (NamingException ex) {
         ex.printStackTrace();
      }
      brConsoleReader = 
      new BufferedReader(new InputStreamReader(System.in));
   }
   
   public static void main(String[] args) {

      EJBTester ejbTester = new EJBTester();

      ejbTester.testEmbeddedObjects();
   }
   
   private void showGUI() {
      System.out.println("**********************");
      System.out.println("Welcome to Book Store");
      System.out.println("**********************");
      System.out.print("Options \n1. Add Book\n2. Exit \nEnter Choice: ");
   }
   
   private void testEmbeddedObjects() {

      try {
         int choice = 1; 

         LibraryPersistentBeanRemote libraryBean = 
        (LibraryPersistentBeanRemote)
         ctx.lookup("LibraryPersistentBean/remote");

         while (choice != 2) {
            String bookName;
            String publisherName;
            String publisherAddress;
            showGUI();
            String strChoice = brConsoleReader.readLine();
            choice = Integer.parseInt(strChoice);
            if (choice == 1) {
               System.out.print("Enter book name: ");
               bookName = brConsoleReader.readLine();
               System.out.print("Enter publisher name: ");
               publisherName = brConsoleReader.readLine();
               System.out.print("Enter publisher address: ");
               publisherAddress = brConsoleReader.readLine();
               Book book = new Book();
               book.setName(bookName);
               book.setPublisher
              (new Publisher(publisherName,publisherAddress));

               libraryBean.addBook(book);          
            } else if (choice == 2) {
               break;
            }
         }

         List<Book> booksList = libraryBean.getBooks();

         System.out.println("Book(s) entered so far: " + booksList.size());
         int i = 0;
         for (Book book:booksList) {
            System.out.println((i+1)+". " + book.getName());
            System.out.println("Publication: "+book.getPublisher());
            i++;
         }           
      } catch (Exception e) {
         System.out.println(e.getMessage());
         e.printStackTrace();
      }finally {
         try {
            if(brConsoleReader !=null) {
               brConsoleReader.close();
            }
         } catch (IOException ex) {
            System.out.println(ex.getMessage());
         }
      }
   }
}

EJBTester ดำเนินการดังต่อไปนี้ -

  • โหลดคุณสมบัติจาก jndi.properties และเริ่มต้นอ็อบเจ็กต์ InitialContext

  • ในเมธอด testInterceptedEjb () การค้นหา jndi จะดำเนินการด้วยชื่อ - "LibraryPersistenceBean / remote" เพื่อรับอ็อบเจ็กต์ธุรกิจระยะไกล (stateless EJB)

  • จากนั้นผู้ใช้จะแสดงส่วนติดต่อผู้ใช้ที่เก็บไลบรารีและระบบจะขอให้ผู้ใช้ป้อนตัวเลือก

  • หากผู้ใช้ป้อน 1 ระบบจะถามชื่อหนังสือและบันทึกหนังสือโดยใช้วิธี stateless session bean addBook () Session Bean กำลังจัดเก็บหนังสือในฐานข้อมูล

  • หากผู้ใช้ป้อน 2 ระบบจะดึงหนังสือโดยใช้เมธอด stateless session bean getBooks () และออก

เรียกใช้ไคลเอ็นต์เพื่อเข้าถึง EJB

ค้นหา EJBTester.java ใน project explorer คลิกขวาที่คลาส EJBTester และเลือกrun file.

ตรวจสอบเอาต์พุตต่อไปนี้ในคอนโซล Netbeans

run:
**********************
Welcome to Book Store
**********************
Options 
1. Add Book
2. Exit 
Enter Choice: 1
Enter book name: learn html5
Enter publisher name: SAMS
Enter publisher address: DELHI
**********************
Welcome to Book Store
**********************
Options 
1. Add Book
2. Exit 
Enter Choice: 2
Book(s) entered so far: 1
1. learn html5
Publication: SAMS,DELHI
BUILD SUCCESSFUL (total time: 21 seconds)

EJB 3.0 ให้การสนับสนุนสำหรับประเภท Blob และ Clob โดยใช้คำอธิบายประกอบ @Lob สามารถแมปประเภท java ต่อไปนี้ได้โดยใช้คำอธิบายประกอบ @Lob

  • java.sql.Blob
  • java.sql.Clob
  • byte[]
  • String
  • วัตถุต่อเนื่อง
@Entity
@Table(name="books")
@EntityListeners(BookCallbackListener.class)
public class Book implements Serializable{
   ...
   private byte[] image;    

   @Lob @Basic(fetch= FetchType.EAGER)
   public byte[] getImage() {
      return image;
   }
   ...
}

ตัวอย่างการใช้งาน

ให้เราสร้างแอปพลิเคชันทดสอบ EJB เพื่อทดสอบการรองรับ blob / clob ใน EJB 3.0

ขั้นตอน คำอธิบาย
1

สร้างโครงการที่มีชื่อEjbComponentภายใต้แพคเกจcom.tutorialspoint.entityตามที่อธิบายไว้ในEJB - สร้างแอพลิเคชันบท โปรดใช้โปรเจ็กต์ที่สร้างขึ้นในEJB - บทความคงอยู่สำหรับบทนี้เพื่อทำความเข้าใจวัตถุก้อน / หยดในแนวคิด ejb

2

สร้างBook.javaภายใต้แพคเกจcom.tutorialspoint.entity ใช้EJB - บทความคงทนเป็นข้อมูลอ้างอิง เก็บไฟล์ที่เหลือไว้ไม่เปลี่ยนแปลง

3

ทำความสะอาดและสร้างแอปพลิเคชันเพื่อให้แน่ใจว่าตรรกะทางธุรกิจทำงานได้ตามข้อกำหนด

4

สุดท้ายปรับใช้แอปพลิเคชันในรูปแบบของไฟล์ jar บน JBoss Application Server เซิร์ฟเวอร์แอปพลิเคชัน JBoss จะเริ่มทำงานโดยอัตโนมัติหากยังไม่เริ่มทำงาน

5

ตอนนี้สร้างไคลเอนต์ EJB ซึ่งเป็นแอปพลิเคชันบนคอนโซลในลักษณะเดียวกับที่อธิบายไว้ในบทEJB - Create Applicationภายใต้หัวข้อCreate Client to access EJB.

สร้าง / แก้ไขตารางหนังสือ

CREATE TABLE book (
   id     integer PRIMARY KEY,
   name   varchar(50)
);
Alter table book add image bytea;
Alter table book add xml text;

ส่วนประกอบ EJBC (โมดูล EJB)

Book.java

package com.tutorialspoint.entity;

import com.tutorialspoint.callback.BookCallbackListener;
import java.io.Serializable;
import javax.persistence.Basic;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.EntityListeners;
import javax.persistence.FetchType;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.Lob;
import javax.persistence.Table;

@Entity
@Table(name="book")
public class Book implements Serializable{
    
   private int id;
   private String name;    
   private byte[] image;   
   private String xml;

   public Book() {        
   }

   @Id
   @GeneratedValue(strategy= GenerationType.IDENTITY)
   @Column(name="id")
   public int getId() {
      return id;
   }

   public void setId(int id) {
      this.id = id;
   }

   public String getName() {
      return name;
   }

   public void setName(String name) {
      this.name = name;
   }

   @Lob @Basic(fetch= FetchType.EAGER)
   public byte[] getImage() {
      return image;
   }

   public void setImage(byte[] image) {
      this.image = image;
   }

   @Lob @Basic(fetch= FetchType.EAGER)
   public String getXml() {
      return xml;
   }

   public void setXml(String xml) {
      this.xml = xml;
   }
}

LibraryPersistentBeanRemote.java

package com.tutorialspoint.stateless;

import com.tutorialspoint.entity.Book;
import java.util.List;
import javax.ejb.Remote;

@Remote
public interface LibraryPersistentBeanRemote {

   void addBook(Book bookName);

   List<Book> getBooks();
    
}

LibraryPersistentBean.java

package com.tutorialspoint.stateless;

import com.tutorialspoint.entity.Book;
import java.util.List;
import javax.ejb.Stateless;
import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;

@Stateless
public class LibraryPersistentBean implements LibraryPersistentBeanRemote {
    
   public LibraryPersistentBean() {
   }

   @PersistenceContext(unitName="EjbComponentPU")
   private EntityManager entityManager;         

   public void addBook(Book book) {
      entityManager.persist(book);
   }    

   public List<Book> getBooks() {
      return entityManager.createQuery("From Book").getResultList();
   }
}
  • ทันทีที่คุณปรับใช้โครงการ EjbComponent บน JBOSS ให้สังเกตบันทึก jboss

  • JBoss ได้สร้างรายการ JNDI สำหรับถั่วเซสชันของเราโดยอัตโนมัติ - LibraryPersistentBean/remote.

  • เราจะใช้สตริงการค้นหานี้เพื่อรับวัตถุทางธุรกิจระยะไกลประเภท - com.tutorialspoint.interceptor.LibraryPersistentBeanRemote

เอาต์พุตบันทึกของเซิร์ฟเวอร์แอปพลิเคชัน JBoss

...
16:30:01,401 INFO  [JndiSessionRegistrarBase] Binding the following Entries in Global JNDI:
   LibraryPersistentBean/remote - EJB3.x Default Remote Business Interface
   LibraryPersistentBean/remote-com.tutorialspoint.interceptor.LibraryPersistentBeanRemote - EJB3.x Remote Business Interface
16:30:02,723 INFO  [SessionSpecContainer] Starting jboss.j2ee:jar=EjbComponent.jar,name=LibraryPersistentBean,service=EJB3
16:30:02,723 INFO  [EJBContainer] STARTED EJB: com.tutorialspoint.interceptor.LibraryPersistentBeanRemote ejbName: LibraryPersistentBean
16:30:02,731 INFO  [JndiSessionRegistrarBase] Binding the following Entries in Global JNDI:

   LibraryPersistentBean/remote - EJB3.x Default Remote Business Interface
   LibraryPersistentBean/remote-com.tutorialspoint.interceptor.LibraryPersistentBeanRemote - EJB3.x Remote Business Interface
...

EJBTester (ไคลเอนต์ EJB)

jndi.properties

java.naming.factory.initial=org.jnp.interfaces.NamingContextFactory
java.naming.factory.url.pkgs=org.jboss.naming:org.jnp.interfaces
java.naming.provider.url=localhost
  • คุณสมบัติเหล่านี้ใช้เพื่อเริ่มต้นอ็อบเจ็กต์ InitialContext ของบริการการตั้งชื่อ java

  • วัตถุ InitialContext จะถูกใช้เพื่อค้นหาเซสชัน bean ที่ไม่มีสถานะ

EJBTester.java

package com.tutorialspoint.test;
   
import com.tutorialspoint.stateful.LibraryBeanRemote;
import java.io.BufferedReader;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.List;
import java.util.Properties;
import javax.naming.InitialContext;
import javax.naming.NamingException;

public class EJBTester {

   BufferedReader brConsoleReader = null; 
   Properties props;
   InitialContext ctx;
   {
      props = new Properties();
      try {
         props.load(new FileInputStream("jndi.properties"));
      } catch (IOException ex) {
         ex.printStackTrace();
      }
      try {
         ctx = new InitialContext(props);            
      } catch (NamingException ex) {
         ex.printStackTrace();
      }
      brConsoleReader = 
      new BufferedReader(new InputStreamReader(System.in));
   }
   
   public static void main(String[] args) {

      EJBTester ejbTester = new EJBTester();

      ejbTester.testBlobClob();
   }
   
   private void showGUI() {
      System.out.println("**********************");
      System.out.println("Welcome to Book Store");
      System.out.println("**********************");
      System.out.print("Options \n1. Add Book\n2. Exit \nEnter Choice: ");
   }
   
   private void testBlobClob() {

      try {
         int choice = 1; 

         LibraryPersistentBeanRemote libraryBean = 
        (LibraryPersistentBeanRemote)
         ctx.lookup("LibraryPersistentBean/remote");

         while (choice != 2) {
            String bookName;
            String publisherName;
            String publisherAddress;
            showGUI();
            String strChoice = brConsoleReader.readLine();
            choice = Integer.parseInt(strChoice);
            if (choice == 1) {
               System.out.print("Enter book name: ");
               bookName = brConsoleReader.readLine();
               String xml = "<book><name>"+bookName+"</name></book>";
               Book book = new Book();
               book.setName(bookName);                                        
               byte[] imageBytes = {0x32, 0x32,0x32, 0x32,0x32,
               0x32,0x32, 0x32,
               0x32, 0x32,0x32, 0x32,0x32, 0x32,0x32, 0x32,
               0x32, 0x32,0x32, 0x32,0x32, 0x32,0x32, 0x32
               };
               book.setImage(imageBytes);
               book.setXml(xml);

               libraryBean.addBook(book);          
            } else if (choice == 2) {
               break;
            }
         }

         List<Book> booksList = libraryBean.getBooks();

         System.out.println("Book(s) entered so far: " + booksList.size());
         int i = 0;
         for (Book book:booksList) {
            System.out.println((i+1)+". " + book.getName());
            byte[] imageByts = book.getImage();
            if(imageByts != null) {
               System.out.print("image bytes: [");
               for(int j = 0; j < imageByts.length ; j++) {
                  System.out.print("0x" 
                  + String.format("%x", imageByts[j]) +" ");
               }            
               System.out.println("]");
            }        
            System.out.println(book.getXml());
            i++;
         }           
      } catch (Exception e) {
         System.out.println(e.getMessage());
         e.printStackTrace();
      }finally {
         try {
            if(brConsoleReader !=null) {
               brConsoleReader.close();
            }
         } catch (IOException ex) {
            System.out.println(ex.getMessage());
         }
      }
   }
}

EJBTester ดำเนินการต่อไปนี้

  • โหลดคุณสมบัติจาก jndi.properties และเริ่มต้นอ็อบเจ็กต์ InitialContext

  • ในเมธอด testInterceptedEjb () การค้นหา jndi จะดำเนินการด้วยชื่อ - "LibraryPersistenceBean / remote" เพื่อรับวัตถุทางธุรกิจระยะไกล (EJB ไร้สัญชาติ)

  • จากนั้นผู้ใช้จะแสดงส่วนติดต่อผู้ใช้ที่เก็บไลบรารีและระบบจะขอให้ผู้ใช้ป้อนตัวเลือก

  • หากผู้ใช้ป้อน 1 ระบบจะถามชื่อหนังสือและบันทึกหนังสือโดยใช้วิธี stateless session bean addBook () Session Bean กำลังจัดเก็บหนังสือในฐานข้อมูล

  • หากผู้ใช้ป้อน 2 ระบบจะดึงหนังสือโดยใช้เมธอด stateless session bean getBooks () และออก

เรียกใช้ไคลเอ็นต์เพื่อเข้าถึง EJB

ค้นหา EJBTester.java ใน project explorer คลิกขวาที่คลาส EJBTester และเลือกrun file.

ตรวจสอบเอาต์พุตต่อไปนี้ในคอนโซล Netbeans

run:
**********************
Welcome to Book Store
**********************
Options 
1. Add Book
2. Exit 
Enter Choice: 1
Enter book name: learn testing
**********************
Welcome to Book Store
**********************
Options 
1. Add Book
2. Exit 
Enter Choice: 2
Book(s) entered so far: 1
1. learn testing
image bytes: [
   0x32 0x32 0x32 0x32 0x32 0x32 0x32 0x32 0x32 0x32 0x32 0x32 0x32 0x32 0x32 0x32 0x32 0x32 0x32 0x32 0x32 0x32 0x32 0x32 ]
<book><name>learn testing</name></book>
BUILD SUCCESSFUL (total time: 20 seconds)

ธุรกรรมคือหน่วยงานเดียวซึ่งเป็นไปตามคุณสมบัติของกรด ACID ย่อมาจาก Atomic, Consistent, Isolated และ Durable

  • Atomic- หากรายการงานใดล้มเหลวจะถือว่าล้มเหลวทั้งหน่วย ความสำเร็จหมายถึงทุกรายการดำเนินการสำเร็จ

  • Consistent - ธุรกรรมต้องทำให้ระบบอยู่ในสถานะที่สอดคล้องกัน

  • Isolated - ธุรกรรมแต่ละรายการดำเนินการโดยไม่ขึ้นกับธุรกรรมอื่นใด

  • Durable - ธุรกรรมควรจะรอดพ้นจากความล้มเหลวของระบบหากมีการดำเนินการหรือกระทำ

EJB Container / Servers คือเซิร์ฟเวอร์ธุรกรรมและจัดการการขยายบริบทธุรกรรมและธุรกรรมแบบกระจาย ธุรกรรมสามารถจัดการได้โดยคอนเทนเนอร์หรือโดยการจัดการโค้ดที่กำหนดเองในโค้ดของ bean

  • Container Managed Transactions - ในประเภทนี้คอนเทนเนอร์จะจัดการสถานะธุรกรรม

  • Bean Managed Transactions - ในประเภทนี้นักพัฒนาจะจัดการวงจรชีวิตของสถานะธุรกรรม

ธุรกรรมที่มีการจัดการคอนเทนเนอร์

EJB 3.0 ได้ระบุแอตทริบิวต์ของธุรกรรมดังต่อไปนี้ซึ่งคอนเทนเนอร์ EJB นำไปใช้ -

  • REQUIRED - ระบุว่าวิธีการทางธุรกิจต้องดำเนินการภายในธุรกรรมมิฉะนั้นธุรกรรมใหม่จะเริ่มต้นสำหรับวิธีการนั้น

  • REQUIRES_NEW - ระบุว่าธุรกรรมใหม่กำลังจะเริ่มต้นสำหรับวิธีการทางธุรกิจ

  • SUPPORTS - ระบุว่าวิธีการทางธุรกิจจะดำเนินการเป็นส่วนหนึ่งของธุรกรรม

  • NOT_SUPPORTED - ระบุว่าไม่ควรใช้วิธีการทางธุรกิจเป็นส่วนหนึ่งของธุรกรรม

  • MANDATORY - ระบุว่าวิธีการทางธุรกิจจะดำเนินการโดยเป็นส่วนหนึ่งของธุรกรรมมิฉะนั้นจะถูกโยนข้อยกเว้น

  • NEVER - ระบุว่าวิธีการทางธุรกิจดำเนินการเป็นส่วนหนึ่งของการทำธุรกรรมข้อยกเว้นจะถูกโยนทิ้ง

ตัวอย่าง

package com.tutorialspoint.txn.required;
 
import javax.ejb.*
 
@Stateless
@TransactionManagement(TransactionManagementType.CONTAINER)
public class UserDetailBean implements UserDetailRemote {
	
   private UserDetail;

   @TransactionAttribute(TransactionAttributeType.REQUIRED)
   public void createUserDetail() {
      //create user details object
   }
}

สร้างวิธีการทางธุรกิจ createUserDetail () จำเป็นโดยใช้คำอธิบายประกอบที่จำเป็น

package com.tutorialspoint.txn.required;
 
import javax.ejb.*
 
@Stateless
public class UserSessionBean implements UserRemote {
	
   private User;

   @EJB
   private UserDetailRemote userDetail;

   public void createUser() {
      //create user 
      //...
      //create user details
      userDetail.createUserDetail();
   }
}

เมธอดธุรกิจ createUser () ใช้ createUserDetail () หากมีข้อยกเว้นเกิดขึ้นระหว่างการเรียก createUser () และไม่ได้สร้างวัตถุ User วัตถุ UserDetail จะไม่ถูกสร้างขึ้นด้วย

ธุรกรรมที่จัดการโดยถั่ว

ใน Bean Managed Transactions สามารถจัดการธุรกรรมได้โดยจัดการข้อยกเว้นที่ระดับแอปพลิเคชัน

ต่อไปนี้เป็นประเด็นสำคัญที่ต้องพิจารณา -

  • Start - จะเริ่มทำธุรกรรมด้วยวิธีการทางธุรกิจเมื่อใด

  • Sucess - ระบุสถานการณ์ความสำเร็จเมื่อต้องทำธุรกรรม

  • Failed - ระบุสถานการณ์ความล้มเหลวเมื่อธุรกรรมจะถูกย้อนกลับ

ตัวอย่าง

package com.tutorialspoint.txn.bmt;
 
import javax.annotation.Resource;
import javax.ejb.Stateless;
import javax.ejb.TransactionManagement;
import javax.ejb.TransactionManagementType;
import javax.transaction.UserTransaction;
 
@Stateless
@TransactionManagement(value=TransactionManagementType.BEAN)
public class AccountBean implements AccountBeanLocal {
 
   @Resource
   private UserTransaction userTransaction;

   public void transferFund(Account fromAccount, double fund , 
      Account toAccount) throws Exception{

      try{
         userTransaction.begin();

         confirmAccountDetail(fromAccount);
         withdrawAmount(fromAccount,fund);

         confirmAccountDetail(toAccount);
         depositAmount(toAccount,fund);

         userTransaction.commit();
      }catch (InvalidAccountException exception) {
         userTransaction.rollback();
      }catch (InsufficientFundException exception) {
         userTransaction.rollback();
      }catch (PaymentException exception) {
         userTransaction.rollback();
      }
   }

   private void confirmAccountDetail(Account account) 
      throws InvalidAccountException {
   }

   private void withdrawAmount() throws InsufficientFundException {
   }

   private void depositAmount() throws PaymentException{
   }
}

ในตัวอย่างนี้เราใช้ประโยชน์จากไฟล์ UserTransaction อินเทอร์เฟซเพื่อทำเครื่องหมายจุดเริ่มต้นของธุรกรรมโดยใช้ userTransaction.begin()วิธีโทร. เราทำเครื่องหมายว่าเสร็จสิ้นการทำธุรกรรมโดยใช้userTransaction.commit() วิธีการและหากมีข้อยกเว้นใด ๆ เกิดขึ้นระหว่างการทำธุรกรรมเราจะย้อนกลับธุรกรรมทั้งหมดโดยใช้ userTransaction.rollback() วิธีโทร.

ความปลอดภัยเป็นข้อกังวลหลักของแอปพลิเคชันระดับองค์กร รวมถึงการระบุตัวผู้ใช้หรือระบบที่เข้าถึงแอปพลิเคชัน จากการระบุตัวตนอนุญาตหรือปฏิเสธการเข้าถึงทรัพยากรภายในแอปพลิเคชัน คอนเทนเนอร์ EJB จัดการข้อกังวลด้านความปลอดภัยมาตรฐานหรือสามารถปรับแต่งเพื่อจัดการกับข้อกังวลด้านความปลอดภัยเฉพาะใด ๆ

เงื่อนไขความปลอดภัยที่สำคัญ

  • Authentication - นี่คือกระบวนการตรวจสอบว่าผู้ใช้ที่เข้าถึงระบบหรือแอปพลิเคชันได้รับการตรวจสอบว่าเป็นของจริง

  • Authorization - นี่คือกระบวนการตรวจสอบให้แน่ใจว่าผู้ใช้ที่แท้จริงมีสิทธิ์ในระดับที่เหมาะสมในการเข้าถึงทรัพยากรระบบ

  • User - ผู้ใช้แสดงถึงไคลเอนต์หรือระบบซึ่งเข้าถึงแอปพลิเคชัน

  • User Groups - ผู้ใช้อาจเป็นส่วนหนึ่งของกลุ่มที่มีหน่วยงานบางอย่างเช่นกลุ่มผู้ดูแลระบบ

  • User Roles - บทบาทกำหนดระดับของอำนาจผู้ใช้มีหรือสิทธิ์ในการเข้าถึงทรัพยากรระบบ

ความปลอดภัยที่มีการจัดการคอนเทนเนอร์

EJB 3.0 ได้ระบุแอตทริบิวต์ / คำอธิบายประกอบด้านความปลอดภัยดังต่อไปนี้ซึ่งคอนเทนเนอร์ EJB นำไปใช้

  • DeclareRoles- ระบุว่าชั้นเรียนจะยอมรับบทบาทที่ประกาศไว้ มีการใช้คำอธิบายประกอบในระดับชั้นเรียน

  • RolesAllowed- ระบุว่าผู้ใช้ของบทบาทที่ระบุสามารถเข้าถึงเมธอดได้ สามารถนำไปใช้ในระดับคลาสซึ่งเป็นผลให้เมธอดคลาสทั้งหมดสามารถเข้าถึงได้ buy user of role ที่ระบุ

  • PermitAll- ระบุว่าทุกคนสามารถเข้าถึงวิธีการทางธุรกิจได้ สามารถนำไปใช้ในชั้นเรียนและในระดับวิธีการ

  • DenyAll - ระบุว่าวิธีการทางธุรกิจไม่สามารถเข้าถึงได้โดยผู้ใช้ใด ๆ ที่ระบุในคลาสหรือที่ระดับเมธอด

ตัวอย่าง

package com.tutorialspoint.security.required;
 
import javax.ejb.*
 
@Stateless
@DeclareRoles({"student" "librarian"})
public class LibraryBean implements LibraryRemote {

   @RolesAllowed({"librarian"})
   public void delete(Book book) {
	  //delete book
   }
   
   @PermitAll
   public void viewBook(Book book) {
      //view book
   }
   
   @DenyAll
   public void deleteAll() {
      //delete all books
   } 
}

การกำหนดค่าความปลอดภัย

แมปบทบาทและกลุ่มผู้ใช้ในไฟล์คอนฟิกูเรชัน

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE sun-ejb-jar PUBLIC "-//Sun Microsystems, Inc.//DTD Application Server 9.0 EJB 3.0//EN" "http://www.sun.com/software/appserver/dtds/sun-ejb-jar_3_0-0.dtd">
<ejb-jar>
   <security-role-mapping>
      <role-name>student</role-name>
      <group-name>student-group</group-name>
   </security-role-mapping>
   <security-role-mapping>
      <role-name>librarian</role-name>
      <group-name>librarian-group</group-name>
   </security-role-mapping>  
   <enterprise-beans/>
</ejb-jar>

JNDI ย่อมาจาก Java Naming และ Directory Interface เป็นชุดของอินเตอร์เฟส API และบริการ แอ็พพลิเคชันที่ใช้ Java ใช้ JNDI สำหรับการตั้งชื่อและบริการไดเร็กทอรี ในบริบทของ EJB มีสองคำ

  • Binding - หมายถึงการกำหนดชื่อให้กับออบเจ็กต์ EJB ซึ่งสามารถใช้ได้ในภายหลัง

  • Lookup - หมายถึงการค้นหาและรับวัตถุของ EJB

ใน Jboss ถั่วเซสชั่นจะถูกผูกไว้ใน JNDI ในรูปแบบต่อไปนี้โดยค่าเริ่มต้น

  • local - ชื่อ EJB / ท้องถิ่น

  • remote - ชื่อ EJB / รีโมท

ในกรณีที่ EJB มาพร้อมกับไฟล์ <application-name> .ear จากนั้นรูปแบบเริ่มต้นจะเป็นดังนี้ -

  • local - ชื่อแอปพลิเคชัน / ejb-name / local

  • remote - ชื่อแอปพลิเคชัน / ejb-name / remote

ตัวอย่างการรวมค่าเริ่มต้น

อ้างถึงEJB - สร้างเอาต์พุตคอนโซล JBoss ของบทแอปพลิเคชัน

เอาต์พุตบันทึกของเซิร์ฟเวอร์แอปพลิเคชัน JBoss

...
16:30:02,723 INFO  [SessionSpecContainer] Starting jboss.j2ee:jar=EjbComponent.jar,name=LibrarySessionBean,service=EJB3
16:30:02,723 INFO  [EJBContainer] STARTED EJB: com.tutorialspoint.stateless.LibrarySessionBean ejbName: LibrarySessionBean
16:30:02,731 INFO  [JndiSessionRegistrarBase] Binding the following Entries in Global JNDI:

   LibrarySessionBean/remote - EJB3.x Default Remote Business Interface
   LibrarySessionBean/remote-com.tutorialspoint.stateless.LibrarySessionBeanRemote - EJB3.x Remote Business Interface
...

การผูกแบบกำหนดเอง

คำอธิบายประกอบต่อไปนี้สามารถใช้เพื่อปรับแต่งการผูก JNDI เริ่มต้น -

  • local - org.jboss.ejb3.LocalBinding

  • remote - org.jboss.ejb3.RemoteBindings

อัปเดต LibrarySessionBean.java อ้างถึงEJB - สร้างแอปพลิเคชันบท

ห้องสมุดเซสชันถั่ว

package com.tutorialspoint.stateless;
 
import java.util.ArrayList;
import java.util.List;
import javax.ejb.Stateless;
 
@Stateless
@LocalBinding(jndiBinding="tutorialsPoint/librarySession")
public class LibrarySessionBean implements LibrarySessionBeanLocal {
    
    List<String> bookShelf;    
    
    public LibrarySessionBean() {
       bookShelf = new ArrayList<String>();
    }
    
    public void addBook(String bookName) {
       bookShelf.add(bookName);
    }    
 
    public List<String> getBooks() {
        return bookShelf;
    }
}

LibrarySessionBeanLocal

package com.tutorialspoint.stateless;
 
import java.util.List;
import javax.ejb.Local;
 
@Local
public interface LibrarySessionBeanLocal {
 
    void addBook(String bookName);
 
    List getBooks();
    
}

สร้างโครงการปรับใช้แอปพลิเคชันบน Jboss และตรวจสอบเอาต์พุตต่อไปนี้ในคอนโซล Jboss -

...
16:30:02,723 INFO  [SessionSpecContainer] Starting jboss.j2ee:jar=EjbComponent.jar,name=LibrarySessionBean,service=EJB3
16:30:02,723 INFO  [EJBContainer] STARTED EJB: com.tutorialspoint.stateless.LibrarySessionBean ejbName: LibrarySessionBean
16:30:02,731 INFO  [JndiSessionRegistrarBase] Binding the following Entries in Global JNDI:

   tutorialsPoint/librarySession - EJB3.x Default Local Business Interface
   tutorialsPoint/librarySession-com.tutorialspoint.stateless.LibrarySessionBeanLocal - EJB3.x Local Business Interface
...

EJB 3.0 มีตัวเลือกในการกำหนดความสัมพันธ์ / การแมปเอนทิตีฐานข้อมูลเช่นความสัมพันธ์แบบหนึ่งต่อหนึ่งแบบหนึ่งต่อหลายแบบหลายต่อหนึ่งและแบบกลุ่มต่อกลุ่ม

ต่อไปนี้เป็นคำอธิบายประกอบที่เกี่ยวข้อง -

  • One-to-One- วัตถุมีความสัมพันธ์แบบหนึ่งต่อหนึ่ง ตัวอย่างเช่นผู้โดยสารสามารถเดินทางโดยใช้ตั๋วใบเดียวต่อครั้ง

  • One-to-Many- ออบเจ็กต์มีความสัมพันธ์แบบหนึ่งต่อกลุ่ม ตัวอย่างเช่นพ่อสามารถมีลูกได้หลายคน

  • Many-to-One- วัตถุมีความสัมพันธ์แบบกลุ่มต่อหนึ่ง ตัวอย่างเช่นเด็กหลายคนมีแม่คนเดียว

  • Many-to-Many- วัตถุมีความสัมพันธ์แบบกลุ่มต่อกลุ่ม ตัวอย่างเช่นหนังสือสามารถมีผู้แต่งหลายคนและผู้แต่งสามารถเขียนหนังสือได้หลายเล่ม

เราจะสาธิตการใช้แผนที่ ManyToMany ที่นี่ ในการแสดงความสัมพันธ์ ManyToMany จำเป็นต้องมีสามตารางต่อไปนี้ -

  • Book - โต๊ะหนังสือมีบันทึกหนังสือ

  • Author - ตารางผู้แต่งมีบันทึกผู้แต่ง

  • Book_Author - ตารางผู้แต่งหนังสือที่มีการเชื่อมโยงของตารางหนังสือและผู้แต่งดังกล่าวข้างต้น

สร้างตาราง

สร้างตาราง book author, book_author ในฐานข้อมูลเริ่มต้น postgres.

CREATE TABLE book (
   book_id     integer,   
   name   varchar(50)      
);

CREATE TABLE author (
   author_id   integer,
   name   varchar(50)      
);

CREATE TABLE book_author (
   book_id     integer,
   author_id   integer 
);

สร้างคลาสเอนทิตี

@Entity
@Table(name="author")
public class Author implements Serializable{
   private int id;
   private String name;
   ...   
}

@Entity
@Table(name="book")
public class Book implements Serializable{
   private int id;
   private String title;
   private Set<Author> authors;
   ...   
}

ใช้คำอธิบายประกอบ ManyToMany ในเอนทิตีหนังสือ

@Entity
public class Book implements Serializable{
   ...
   @ManyToMany(cascade = {CascadeType.PERSIST, CascadeType.MERGE}
      , fetch = FetchType.EAGER)
   @JoinTable(table = @Table(name = "book_author"),
      joinColumns = {@JoinColumn(name = "book_id")},
      inverseJoinColumns = {@JoinColumn(name = "author_id")})
   public Set<Author> getAuthors() {
      return authors;
   }
   ...
}

ตัวอย่างการใช้งาน

ให้เราสร้างแอปพลิเคชันทดสอบ EJB เพื่อทดสอบวัตถุความสัมพันธ์ของเอนทิตีใน EJB 3.0

ขั้นตอน คำอธิบาย
1

สร้างโครงการที่มีชื่อEjbComponentภายใต้แพคเกจcom.tutorialspoint.entityตามที่อธิบายไว้ในEJB - สร้างแอพลิเคชันบท โปรดใช้โปรเจ็กต์ที่สร้างขึ้นในEJB - บทความคงอยู่สำหรับบทนี้เพื่อทำความเข้าใจอ็อบเจ็กต์ฝังตัวในแนวคิด EJB

2

สร้างAuthor.javaภายใต้แพคเกจcom.tutorialspoint.entityตามที่อธิบายไว้ในEJB - สร้างแอพลิเคชันบท เก็บไฟล์ที่เหลือไว้ไม่เปลี่ยนแปลง

3

สร้างBook.javaภายใต้แพคเกจcom.tutorialspoint.entity ใช้EJB - บทความคงทนเป็นข้อมูลอ้างอิง เก็บไฟล์ที่เหลือไว้ไม่เปลี่ยนแปลง

4

ทำความสะอาดและสร้างแอปพลิเคชันเพื่อให้แน่ใจว่าตรรกะทางธุรกิจทำงานได้ตามข้อกำหนด

5

สุดท้ายปรับใช้แอปพลิเคชันในรูปแบบของไฟล์ jar บน JBoss Application Server เซิร์ฟเวอร์แอปพลิเคชัน JBoss จะเริ่มทำงานโดยอัตโนมัติหากยังไม่เริ่มทำงาน

6

ตอนนี้สร้างไคลเอนต์ EJB ซึ่งเป็นแอปพลิเคชันบนคอนโซลในลักษณะเดียวกับที่อธิบายไว้ในบทEJB - Create Applicationภายใต้หัวข้อCreate Client to access EJB.

ส่วนประกอบ EJBC (โมดูล EJB)

Author.java

package com.tutorialspoint.entity;

import java.io.Serializable;

import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.Table;

@Entity
@Table(name="author")
public class Author implements Serializable{
    
   private int id;
   private String name;

   public Author() {}

   public Author(int id, String name) {
      this.id = id;
      this.name = name;
   }
   
   @Id  
   @GeneratedValue(strategy= GenerationType.IDENTITY)
   @Column(name="author_id")
   public int getId() {
      return id;
   }

   public void setId(int id) {
      this.id = id;
   }

   public String getName() {
      return name;
   }

   public void setName(String name) {
      this.name = name;
   }

   public String toString() {
      return id + "," + name;
   }    
}

Book.java

package com.tutorialspoint.entity;

import java.io.Serializable;

import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.Table;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;

@Entity
@Table(name="book")
public class Book implements Serializable{

   private int id;
   private String name;
   private Set<Author> authors;

   public Book() {        
   }

   @Id  
   @GeneratedValue(strategy= GenerationType.IDENTITY)
   @Column(name="book_id")
   public int getId() {
      return id;
   }

   public void setId(int id) {
      this.id = id;
   }

   public String getName() {
      return name;
   }

   public void setName(String name) {
      this.name = name;
   }

   public void setAuthors(Set<Author> authors) {
      this.authors = authors;
   }    
   
   @ManyToMany(cascade = {CascadeType.PERSIST, CascadeType.MERGE}
      , fetch = FetchType.EAGER)
   @JoinTable(table = @Table(name = "book_author"),
      joinColumns = {@JoinColumn(name = "book_id")},
      inverseJoinColumns = {@JoinColumn(name = "author_id")})
   public Set<Author> getAuthors() {
      return authors;
   }
}

LibraryPersistentBeanRemote.java

package com.tutorialspoint.stateless;

import com.tutorialspoint.entity.Book;
import java.util.List;
import javax.ejb.Remote;

@Remote
public interface LibraryPersistentBeanRemote {

   void addBook(Book bookName);

   List<Book> getBooks();
    
}

LibraryPersistentBean.java

package com.tutorialspoint.stateless;

import com.tutorialspoint.entity.Book;
import java.util.List;
import javax.ejb.Stateless;

import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;

@Stateless
public class LibraryPersistentBean implements LibraryPersistentBeanRemote {
    
   public LibraryPersistentBean() {
   }

   @PersistenceContext(unitName="EjbComponentPU")
   private EntityManager entityManager;         

   public void addBook(Book book) {
      entityManager.persist(book);
   }    

   public List<Book> getBooks() {
      return entityManager.createQuery("From Book").getResultList();
   }
}
  • ทันทีที่คุณปรับใช้โครงการ EjbComponent บน JBOSS ให้สังเกตบันทึก jboss

  • JBoss ได้สร้างรายการ JNDI สำหรับถั่วเซสชันของเราโดยอัตโนมัติ - LibraryPersistentBean/remote.

  • เราจะใช้สตริงการค้นหานี้เพื่อรับวัตถุทางธุรกิจระยะไกลประเภท - com.tutorialspoint.interceptor.LibraryPersistentBeanRemote

เอาต์พุตบันทึกของเซิร์ฟเวอร์แอปพลิเคชัน JBoss

...
16:30:01,401 INFO  [JndiSessionRegistrarBase] Binding the following Entries in Global JNDI:
   LibraryPersistentBean/remote - EJB3.x Default Remote Business Interface
   LibraryPersistentBean/remote-com.tutorialspoint.interceptor.LibraryPersistentBeanRemote - EJB3.x Remote Business Interface
16:30:02,723 INFO  [SessionSpecContainer] Starting jboss.j2ee:jar=EjbComponent.jar,name=LibraryPersistentBean,service=EJB3
16:30:02,723 INFO  [EJBContainer] STARTED EJB: com.tutorialspoint.interceptor.LibraryPersistentBeanRemote ejbName: LibraryPersistentBean
16:30:02,731 INFO  [JndiSessionRegistrarBase] Binding the following Entries in Global JNDI:

   LibraryPersistentBean/remote - EJB3.x Default Remote Business Interface
   LibraryPersistentBean/remote-com.tutorialspoint.interceptor.LibraryPersistentBeanRemote - EJB3.x Remote Business Interface
...

EJBTester (ไคลเอนต์ EJB)

jndi.properties

java.naming.factory.initial=org.jnp.interfaces.NamingContextFactory
java.naming.factory.url.pkgs=org.jboss.naming:org.jnp.interfaces
java.naming.provider.url=localhost
  • คุณสมบัติเหล่านี้ใช้เพื่อเริ่มต้นอ็อบเจ็กต์ InitialContext ของบริการการตั้งชื่อ java

  • วัตถุ InitialContext จะถูกใช้เพื่อค้นหาเซสชัน bean ที่ไม่มีสถานะ

EJBTester.java

package com.tutorialspoint.test;
   
import com.tutorialspoint.stateful.LibraryBeanRemote;

import java.io.BufferedReader;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStreamReader;

import java.util.*;

import javax.naming.InitialContext;
import javax.naming.NamingException;

public class EJBTester {

   BufferedReader brConsoleReader = null; 
   Properties props;
   InitialContext ctx;
   {
      props = new Properties();
      try {
         props.load(new FileInputStream("jndi.properties"));
      } catch (IOException ex) {
         ex.printStackTrace();
      }
      try {
         ctx = new InitialContext(props);            
      } catch (NamingException ex) {
         ex.printStackTrace();
      }
      brConsoleReader = 
      new BufferedReader(new InputStreamReader(System.in));
   }
   
   public static void main(String[] args) {

      EJBTester ejbTester = new EJBTester();

      ejbTester.testEmbeddedObjects();
   }
   
   private void showGUI() {
      System.out.println("**********************");
      System.out.println("Welcome to Book Store");
      System.out.println("**********************");
      System.out.print("Options \n1. Add Book\n2. Exit \nEnter Choice: ");
   }
   
   private void testEmbeddedObjects() {

      try {
         int choice = 1; 

         LibraryPersistentBeanRemote libraryBean = 
         (LibraryPersistentBeanRemote)
         ctx.lookup("LibraryPersistentBean/remote");

         while (choice != 2) {
            String bookName;
            String authorName;
            
            showGUI();
            String strChoice = brConsoleReader.readLine();
            choice = Integer.parseInt(strChoice);
            if (choice == 1) {
               System.out.print("Enter book name: ");
               bookName = brConsoleReader.readLine();
               System.out.print("Enter author name: ");
               authorName = brConsoleReader.readLine();               
               Book book = new Book();
               book.setName(bookName);
               Author author = new Author();
               author.setName(authorName);
               Set<Author> authors = new HashSet<Author>();
               authors.add(author);
               book.setAuthors(authors);

               libraryBean.addBook(book);          
            } else if (choice == 2) {
               break;
            }
         }

         List<Book> booksList = libraryBean.getBooks();

         System.out.println("Book(s) entered so far: " + booksList.size());
         int i = 0;
         for (Book book:booksList) {
            System.out.println((i+1)+". " + book.getName());
            System.out.print("Author: ");
            Author[] authors = (Author[])books.getAuthors().toArray();
            for(int j=0;j<authors.length;j++) {
               System.out.println(authors[j]);
            }
            i++;
         }           
      } catch (Exception e) {
         System.out.println(e.getMessage());
         e.printStackTrace();
      }finally {
         try {
            if(brConsoleReader !=null) {
               brConsoleReader.close();
            }
         } catch (IOException ex) {
            System.out.println(ex.getMessage());
         }
      }
   }
}

EJBTester ดำเนินการดังต่อไปนี้ -

  • โหลดคุณสมบัติจาก jndi.properties และเริ่มต้นอ็อบเจ็กต์ InitialContext

  • ในเมธอด testInterceptedEjb () การค้นหา jndi จะดำเนินการด้วยชื่อ - "LibraryPersistenceBean / remote" เพื่อรับวัตถุทางธุรกิจระยะไกล (EJB ไร้สัญชาติ)

  • จากนั้นผู้ใช้จะแสดงส่วนติดต่อผู้ใช้ที่เก็บไลบรารีและระบบจะขอให้ผู้ใช้ป้อนตัวเลือก

  • หากผู้ใช้ป้อน 1 ระบบจะถามชื่อหนังสือและบันทึกหนังสือโดยใช้วิธี stateless session bean addBook () Session Bean กำลังจัดเก็บหนังสือในฐานข้อมูล

  • หากผู้ใช้ป้อน 2 ระบบจะดึงหนังสือโดยใช้เมธอด stateless session bean getBooks () และออก

เรียกใช้ไคลเอ็นต์เพื่อเข้าถึง EJB

ค้นหา EJBTester.java ใน project explorer คลิกขวาที่คลาส EJBTester และเลือกrun file.

ตรวจสอบเอาต์พุตต่อไปนี้ในคอนโซล Netbeans

run:
**********************
Welcome to Book Store
**********************
Options 
1. Add Book
2. Exit 
Enter Choice: 1
Enter book name: learn html5
Enter Author name: Robert
**********************
Welcome to Book Store
**********************
Options 
1. Add Book
2. Exit 
Enter Choice: 2
Book(s) entered so far: 1
1. learn html5
Author: Robert
BUILD SUCCESSFUL (total time: 21 seconds)

ใน EJB 3.0 กลไกการคงอยู่ใช้เพื่อเข้าถึงฐานข้อมูลที่คอนเทนเนอร์จัดการการดำเนินการที่เกี่ยวข้องกับฐานข้อมูล นักพัฒนาสามารถเข้าถึงฐานข้อมูลโดยใช้การเรียก JDBC API โดยตรงในวิธีการทางธุรกิจของ EJB

เพื่อแสดงการเข้าถึงฐานข้อมูลใน EJB เราจำเป็นต้องดำเนินการดังต่อไปนี้ -

  • Step 1 - สร้างตารางในฐานข้อมูล

  • Step 2 - สร้าง EJB ไร้สัญชาติที่มีธุรกิจกับฉัน

  • Step 3- อัปเดต EJB ไร้สัญชาติ เพิ่มวิธีการเพิ่มเรกคอร์ดและรับเรกคอร์ดจากฐานข้อมูลผ่านตัวจัดการเอนทิตี

  • Step 4 - ไคลเอนต์แอปพลิเคชันที่ใช้คอนโซลจะเข้าถึง EJB แบบไม่ระบุสถานะเพื่อคงข้อมูลในฐานข้อมูล

สร้างตาราง

สร้างตาราง books ในฐานข้อมูลเริ่มต้น postgres.

CREATE TABLE books (
   id     integer PRIMARY KEY,
   name   varchar(50)
);

สร้างคลาสโมเดล

public class Book implements Serializable{
    
   private int id;
   private String name;

   public Book() {        
   }
   
   public int getId() {
      return id;
   }
   ...
}

สร้าง EJB ไร้สัญชาติ

@Stateless
public class LibraryPersistentBean implements LibraryPersistentBeanRemote {
	
   public void addBook(Book book) {
     //persist book using jdbc calls
   }    

   public List<Book> getBooks() {        
     //get books using jdbc calls
   }
   ...
}

หลังจากสร้างโมดูล EJB แล้วเราจำเป็นต้องมีไคลเอนต์เพื่อเข้าถึงถั่วไร้สัญชาติซึ่งเราจะสร้างในส่วนถัดไป

ตัวอย่างการใช้งาน

ให้เราสร้างแอปพลิเคชันทดสอบ EJB เพื่อทดสอบกลไกการเข้าถึงฐานข้อมูล EJB

ขั้นตอน คำอธิบาย
1

สร้างโครงการที่มีชื่อEjbComponentภายใต้แพคเกจcom.tutorialspoint.entityตามที่อธิบายไว้ในEJB - สร้างแอพลิเคชันบท คุณยังสามารถใช้โครงการที่สร้างในEJB - สร้างบทแอปพลิเคชันสำหรับบทนี้เพื่อทำความเข้าใจแนวคิดการเข้าถึงข้อมูล EJB

2

สร้างBook.javaภายใต้แพ็คเกจcom.tutorialspoint.entityและแก้ไขตามที่แสดงด้านล่าง

3

สร้างLibraryPersistentBean.javaและLibraryPersistentBeanRemoteตามที่อธิบายไว้ในบทEJB - Create Applicationและแก้ไขตามที่แสดงด้านล่าง

4

ทำความสะอาดและสร้างแอปพลิเคชันเพื่อให้แน่ใจว่าตรรกะทางธุรกิจทำงานได้ตามข้อกำหนด

5

สุดท้ายปรับใช้แอปพลิเคชันในรูปแบบของไฟล์ jar บน JBoss Application Server เซิร์ฟเวอร์แอปพลิเคชัน JBoss จะเริ่มทำงานโดยอัตโนมัติหากยังไม่เริ่มทำงาน

6

ตอนนี้สร้างไคลเอนต์ EJB ซึ่งเป็นแอปพลิเคชันบนคอนโซลในลักษณะเดียวกับที่อธิบายไว้ในบทEJB - Create Applicationภายใต้หัวข้อCreate Client to access EJB. แก้ไขตามที่แสดงด้านล่าง

ส่วนประกอบ EJBC (โมดูล EJB)

Book.java

package com.tutorialspoint.entity;

import java.io.Serializable;

public class Book implements Serializable{
    
   private int id;
   private String name;

   public Book() {        
   }
   
   public int getId() {
      return id;
   }

   public void setId(int id) {
      this.id = id;
   }

   public String getName() {
      return name;
   }

   public void setName(String name) {
      this.name = name;
   }    
}

LibraryPersistentBeanRemote.java

package com.tutorialspoint.stateless;

import com.tutorialspoint.entity.Book;
import java.util.List;
import javax.ejb.Remote;

@Remote
public interface LibraryPersistentBeanRemote {

   void addBook(Book bookName);

   List<Book> getBooks();
    
}

LibraryPersistentBean.java

package com.tutorialspoint.stateless;

import com.tutorialspoint.entity.Book;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.ArrayList;
import java.util.List;
import javax.ejb.Stateless;

@Stateless
public class LibraryPersistentBean implements LibraryPersistentBeanRemote {
    
   public LibraryPersistentBean() {
   }

   public void addBook(Book book) {
      Connection con = null;
      String url = "jdbc:postgresql://localhost:5432/postgres";
      String driver = "org.postgresql.driver";

      String userName = "sa";
      String password = "sa";
      List<Book> books = new ArrayList<Book>();
      try {

         Class.forName(driver).newInstance();
         con = DriverManager.getConnection(url , userName, password);

         PreparedStatement st = 
         con.prepareStatement("insert into book(name) values(?)");
         st.setString(1,book.getName());

         int result = st.executeUpdate();                

      } catch (SQLException ex) {
         ex.printStackTrace();
      } catch (InstantiationException ex) {
         ex.printStackTrace();
      } catch (IllegalAccessException ex) {
         ex.printStackTrace();
      } catch (ClassNotFoundException ex) {
         ex.printStackTrace();
      }    
   }    

   public List<Book> getBooks() {
      Connection con = null;
      String url = "jdbc:postgresql://localhost:5432/postgres";
      String driver = "org.postgresql.driver";
   
      String userName = "sa";
      String password = "sa";
      List<Book> books = new ArrayList<Book>();
      try {

         Class.forName(driver).newInstance();
         con = DriverManager.getConnection(url , userName, password);

         Statement st = con.createStatement();
         ResultSet rs = st.executeQuery("select * from book");

         Book book;
         while (rs.next()) {
            book = new Book();
            book.setId(rs.getInt(1));                 
            book.setName(rs.getString(2));
            books.add(book);
         }
      } catch (SQLException ex) {
         ex.printStackTrace();
      } catch (InstantiationException ex) {
         ex.printStackTrace();
      } catch (IllegalAccessException ex) {
         ex.printStackTrace();
      } catch (ClassNotFoundException ex) {
         ex.printStackTrace();
      }
      return books;
   }
}
  • ทันทีที่คุณปรับใช้โครงการ EjbComponent บน JBOSS ให้สังเกตบันทึก jboss

  • JBoss ได้สร้างรายการ JNDI สำหรับถั่วเซสชันของเราโดยอัตโนมัติ - LibraryPersistentBean/remote.

  • เราจะใช้สตริงการค้นหานี้เพื่อรับวัตถุทางธุรกิจระยะไกลประเภท - com.tutorialspoint.stateless.LibraryPersistentBeanRemote

เอาต์พุตบันทึกของเซิร์ฟเวอร์แอปพลิเคชัน JBoss

...
16:30:01,401 INFO  [JndiSessionRegistrarBase] Binding the following Entries in Global JNDI:
   LibraryPersistentBean/remote - EJB3.x Default Remote Business Interface
   LibraryPersistentBean/remote-com.tutorialspoint.stateless.LibraryPersistentBeanRemote - EJB3.x Remote Business Interface
16:30:02,723 INFO  [SessionSpecContainer] Starting jboss.j2ee:jar=EjbComponent.jar,name=LibraryPersistentBeanRemote,service=EJB3
16:30:02,723 INFO  [EJBContainer] STARTED EJB: com.tutorialspoint.stateless.LibraryPersistentBeanRemote ejbName: LibraryPersistentBean
16:30:02,731 INFO  [JndiSessionRegistrarBase] Binding the following Entries in Global JNDI:

   LibraryPersistentBean/remote - EJB3.x Default Remote Business Interface
   LibraryPersistentBean/remote-com.tutorialspoint.stateless.LibraryPersistentBeanRemote - EJB3.x Remote Business Interface
...

EJBTester (ไคลเอนต์ EJB)

jndi.properties

java.naming.factory.initial=org.jnp.interfaces.NamingContextFactory
java.naming.factory.url.pkgs=org.jboss.naming:org.jnp.interfaces
java.naming.provider.url=localhost
  • คุณสมบัติเหล่านี้ใช้เพื่อเริ่มต้นอ็อบเจ็กต์ InitialContext ของบริการการตั้งชื่อ java

  • วัตถุ InitialContext จะถูกใช้เพื่อค้นหาเซสชัน bean ที่ไม่มีสถานะ

EJBTester.java

package com.tutorialspoint.test;
   
import com.tutorialspoint.stateless.LibraryPersistentBeanRemote;
import java.io.BufferedReader;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.List;
import java.util.Properties;
import javax.naming.InitialContext;
import javax.naming.NamingException;

public class EJBTester {

   BufferedReader brConsoleReader = null; 
   Properties props;
   InitialContext ctx;
   {
      props = new Properties();
      try {
         props.load(new FileInputStream("jndi.properties"));
      } catch (IOException ex) {
         ex.printStackTrace();
      }
      try {
         ctx = new InitialContext(props);            
      } catch (NamingException ex) {
         ex.printStackTrace();
      }
      brConsoleReader = 
      new BufferedReader(new InputStreamReader(System.in));
   }
   
   public static void main(String[] args) {

      EJBTester ejbTester = new EJBTester();

      ejbTester.testEntityEjb();
   }
   
   private void showGUI() {
      System.out.println("**********************");
      System.out.println("Welcome to Book Store");
      System.out.println("**********************");
      System.out.print("Options \n1. Add Book\n2. Exit \nEnter Choice: ");
   }
   
   private void testEntityEjb() {

      try {
         int choice = 1; 

         LibraryPersistentBeanRemote libraryBean =
         LibraryPersistentBeanRemote)
         ctx.lookup("LibraryPersistentBean/remote");

         while (choice != 2) {
            String bookName;
            showGUI();
            String strChoice = brConsoleReader.readLine();
            choice = Integer.parseInt(strChoice);
            if (choice == 1) {
               System.out.print("Enter book name: ");
               bookName = brConsoleReader.readLine();
               Book book = new Book();
               book.setName(bookName);
               libraryBean.addBook(book);          
            } else if (choice == 2) {
               break;
            }
         }

         List<Book> booksList = libraryBean.getBooks();

         System.out.println("Book(s) entered so far: " + booksList.size());
         int i = 0;
         for (Book book:booksList) {
            System.out.println((i+1)+". " + book.getName());
            i++;
         }           
      } catch (Exception e) {
         System.out.println(e.getMessage());
         e.printStackTrace();
      }finally {
         try {
            if(brConsoleReader !=null) {
               brConsoleReader.close();
            }
         } catch (IOException ex) {
            System.out.println(ex.getMessage());
         }
      }
   }
}

EJBTester ดำเนินการดังต่อไปนี้ -

  • โหลดคุณสมบัติจาก jndi.properties และเริ่มต้นอ็อบเจ็กต์ InitialContext

  • ในเมธอด testStatefulEjb () การค้นหา jndi จะดำเนินการด้วยชื่อ - "LibraryStatelessSessionBean / remote" เพื่อรับอ็อบเจ็กต์ธุรกิจระยะไกล (stateful EJB)

  • จากนั้นผู้ใช้จะแสดงส่วนติดต่อผู้ใช้ที่เก็บไลบรารีและระบบจะขอให้ป้อนตัวเลือก

  • หากผู้ใช้ป้อน 1 ระบบจะถามชื่อหนังสือและบันทึกหนังสือโดยใช้วิธี stateless session bean addBook () Session Bean ยังคงมีหนังสืออยู่ในฐานข้อมูลผ่านการเรียก EntityManager

  • หากผู้ใช้ป้อน 2 ระบบจะดึงหนังสือโดยใช้เมธอด stateless session bean getBooks () และออก

  • จากนั้นค้นหา jndi อีกครั้งด้วยชื่อ - "LibraryStatelessSessionBean / remote" เพื่อรับวัตถุทางธุรกิจระยะไกล (EJB ที่มีสถานะ) อีกครั้งและทำรายการหนังสือ

เรียกใช้ไคลเอ็นต์เพื่อเข้าถึง EJB

ค้นหา EJBTester.java ใน project explorer คลิกขวาที่คลาส EJBTester และเลือกrun file.

ตรวจสอบเอาต์พุตต่อไปนี้ในคอนโซล Netbeans

run:
**********************
Welcome to Book Store
**********************
Options 
1. Add Book
2. Exit 
Enter Choice: 1
Enter book name: Learn Java
**********************
Welcome to Book Store
**********************
Options 
1. Add Book
2. Exit 
Enter Choice: 2
Book(s) entered so far: 1
1. learn java
BUILD SUCCESSFUL (total time: 15 seconds)

EJB Query Languageค่อนข้างสะดวกในการเขียนแบบสอบถามที่กำหนดเองโดยไม่ต้องกังวลเกี่ยวกับรายละเอียดฐานข้อมูลพื้นฐาน ค่อนข้างคล้ายกับ HQL ภาษาคิวรีไฮเบอร์เนตและมักเรียกด้วยชื่อ EJBQL

เพื่อสาธิต EJBQL ใน EJB เราจะทำงานต่อไปนี้ -

  • Step 1 - สร้างตารางในฐานข้อมูล

  • Step 2 - สร้าง EJB ไร้สัญชาติที่มีธุรกิจกับฉัน

  • Step 3− อัปเดต EJB ไร้สัญชาติ เพิ่มวิธีการเพิ่มเรกคอร์ดและรับเรกคอร์ดจากฐานข้อมูลผ่านตัวจัดการเอนทิตี

  • Step 4 - ไคลเอนต์แอปพลิเคชันที่ใช้คอนโซลจะเข้าถึง EJB แบบไม่ระบุสถานะเพื่อคงข้อมูลในฐานข้อมูล

สร้างตาราง

สร้างตาราง books ในฐานข้อมูลเริ่มต้น postgres.

CREATE TABLE books (
   id     integer PRIMARY KEY,
   name   varchar(50)
);

สร้างคลาสโมเดล

public class Book implements Serializable{
    
   private int id;
   private String name;

   public Book() {        
   }
   
   public int getId() {
      return id;
   }
   ...
}

สร้าง EJB ไร้สัญชาติ

@Stateless
public class LibraryPersistentBean implements LibraryPersistentBeanRemote {
	
   public void addBook(Book book) {
     //persist book using entity manager
   }    

   public List<Book> getBooks() {        
     //get books using entity manager
   }
   ...
}

หลังจากสร้างโมดูล EJB แล้วเราจำเป็นต้องมีไคลเอนต์เพื่อเข้าถึงถั่วไร้สัญชาติซึ่งเราจะสร้างในส่วนถัดไป

ตัวอย่างการใช้งาน

ให้เราสร้างแอปพลิเคชันทดสอบ EJB เพื่อทดสอบกลไกการเข้าถึงฐานข้อมูล EJB

ขั้นตอน คำอธิบาย
1

สร้างโครงการที่มีชื่อEjbComponentภายใต้แพคเกจcom.tutorialspoint.entityตามที่อธิบายไว้ในEJB - สร้างแอพลิเคชันบท คุณยังสามารถใช้โครงการที่สร้างในEJB - สร้างบทแอปพลิเคชันสำหรับบทนี้เพื่อทำความเข้าใจแนวคิดการเข้าถึงข้อมูล EJB

2

สร้างBook.javaภายใต้แพ็คเกจcom.tutorialspoint.entityและแก้ไขตามที่แสดงด้านล่าง

3

สร้างLibraryPersistentBean.javaและLibraryPersistentBeanRemoteตามที่อธิบายไว้ในบทEJB - Create Applicationและแก้ไขตามที่แสดงด้านล่าง

4

ทำความสะอาดและสร้างแอปพลิเคชันเพื่อให้แน่ใจว่าตรรกะทางธุรกิจทำงานได้ตามข้อกำหนด

5

สุดท้ายปรับใช้แอปพลิเคชันในรูปแบบของไฟล์ jar บน JBoss Application Server เซิร์ฟเวอร์แอปพลิเคชัน JBoss จะเริ่มทำงานโดยอัตโนมัติหากยังไม่เริ่มทำงาน

6

ตอนนี้สร้างไคลเอนต์ EJB ซึ่งเป็นแอปพลิเคชันบนคอนโซลในลักษณะเดียวกับที่อธิบายไว้ในบทEJB - Create Applicationภายใต้หัวข้อCreate Client to access EJB. แก้ไขตามที่แสดงด้านล่าง

ส่วนประกอบ EJBC (โมดูล EJB)

Book.java

package com.tutorialspoint.entity;

import java.io.Serializable;

public class Book implements Serializable{
    
   private int id;
   private String name;

   public Book() {        
   }
   
   public int getId() {
      return id;
   }

   public void setId(int id) {
      this.id = id;
   }

   public String getName() {
      return name;
   }

   public void setName(String name) {
      this.name = name;
   }    
}

LibraryPersistentBeanRemote.java

package com.tutorialspoint.stateless;

import com.tutorialspoint.entity.Book;
import java.util.List;
import javax.ejb.Remote;

@Remote
public interface LibraryPersistentBeanRemote {
   void addBook(Book bookName);
   List<Book> getBooks();
}

LibraryPersistentBean.java

package com.tutorialspoint.stateless;

import com.tutorialspoint.entity.Book;
import java.util.List;
import javax.ejb.Stateless;
import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
import javax.persistence.Query;

@Stateless
public class LibraryPersistentBean implements LibraryPersistentBeanRemote {
    
   public LibraryPersistentBean() {
   }

   @PersistenceContext(unitName="EntityEjbPU")
   private EntityManager entityManager;         

   public void addBook(Book book) {
      entityManager.persist(book);
   }    

   public List<Book> getBooks() {
      //create an ejbql expression
      String ejbQL = "From Book b where b.name like ?1";
      //create query
      Query query = entityManager.createQuery(ejbQL);
      //substitute parameter.
      query.setParameter(1, "%test%");   
      //execute the query
      return query.getResultList();
   }   
}
  • ทันทีที่คุณปรับใช้โครงการ EjbComponent บน JBOSS ให้สังเกตบันทึก jboss

  • JBoss ได้สร้างรายการ JNDI สำหรับถั่วเซสชันของเราโดยอัตโนมัติ - LibraryPersistentBean/remote.

  • เราจะใช้สตริงการค้นหานี้เพื่อรับวัตถุทางธุรกิจระยะไกลประเภท - com.tutorialspoint.stateless.LibraryPersistentBeanRemote

เอาต์พุตบันทึกของเซิร์ฟเวอร์แอปพลิเคชัน JBoss

...
16:30:01,401 INFO  [JndiSessionRegistrarBase] Binding the following Entries in Global JNDI:
   LibraryPersistentBean/remote - EJB3.x Default Remote Business Interface
   LibraryPersistentBean/remote-com.tutorialspoint.stateless.LibraryPersistentBeanRemote - EJB3.x Remote Business Interface
16:30:02,723 INFO  [SessionSpecContainer] Starting jboss.j2ee:jar=EjbComponent.jar,name=LibraryPersistentBeanRemote,service=EJB3
16:30:02,723 INFO  [EJBContainer] STARTED EJB: com.tutorialspoint.stateless.LibraryPersistentBeanRemote ejbName: LibraryPersistentBean
16:30:02,731 INFO  [JndiSessionRegistrarBase] Binding the following Entries in Global JNDI:

   LibraryPersistentBean/remote - EJB3.x Default Remote Business Interface
   LibraryPersistentBean/remote-com.tutorialspoint.stateless.LibraryPersistentBeanRemote - EJB3.x Remote Business Interface
...

EJBTester (ไคลเอนต์ EJB)

jndi.properties

java.naming.factory.initial=org.jnp.interfaces.NamingContextFactory
java.naming.factory.url.pkgs=org.jboss.naming:org.jnp.interfaces
java.naming.provider.url=localhost
  • คุณสมบัติเหล่านี้ใช้เพื่อเริ่มต้นอ็อบเจ็กต์ InitialContext ของบริการการตั้งชื่อ java

  • วัตถุ InitialContext จะถูกใช้เพื่อค้นหาเซสชัน bean ที่ไม่มีสถานะ

EJBTester.java

package com.tutorialspoint.test;
   
import com.tutorialspoint.stateless.LibraryPersistentBeanRemote;
import java.io.BufferedReader;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.List;
import java.util.Properties;
import javax.naming.InitialContext;
import javax.naming.NamingException;

public class EJBTester {

   BufferedReader brConsoleReader = null; 
   Properties props;
   InitialContext ctx;
   {
      props = new Properties();
      try {
         props.load(new FileInputStream("jndi.properties"));
      } catch (IOException ex) {
         ex.printStackTrace();
      }
      try {
         ctx = new InitialContext(props);            
      } catch (NamingException ex) {
         ex.printStackTrace();
      }
      brConsoleReader = 
      new BufferedReader(new InputStreamReader(System.in));
   }
   
   public static void main(String[] args) {

      EJBTester ejbTester = new EJBTester();

      ejbTester.testEntityEjb();
   }
   
   private void showGUI() {
      System.out.println("**********************");
      System.out.println("Welcome to Book Store");
      System.out.println("**********************");
      System.out.print("Options \n1. Add Book\n2. Exit \nEnter Choice: ");
   }
   
   private void testEntityEjb() {

      try {
         int choice = 1; 

         LibraryPersistentBeanRemote libraryBean =
         LibraryPersistentBeanRemote)
         ctx.lookup("LibraryPersistentBean/remote");

         while (choice != 2) {
            String bookName;
            showGUI();
            String strChoice = brConsoleReader.readLine();
            choice = Integer.parseInt(strChoice);
            if (choice == 1) {
               System.out.print("Enter book name: ");
               bookName = brConsoleReader.readLine();
               Book book = new Book();
               book.setName(bookName);
               libraryBean.addBook(book);          
            } else if (choice == 2) {
               break;
            }
         }

         List<Book> booksList = libraryBean.getBooks();

         System.out.println("Book(s) entered so far: " + booksList.size());
         int i = 0;
         for (Book book:booksList) {
            System.out.println((i+1)+". " + book.getName());
            i++;
         }           
      } catch (Exception e) {
         System.out.println(e.getMessage());
         e.printStackTrace();
      }finally {
         try {
            if(brConsoleReader !=null) {
               brConsoleReader.close();
            }
         } catch (IOException ex) {
            System.out.println(ex.getMessage());
         }
      }
   }
}

EJBTester ดำเนินการดังต่อไปนี้ -

  • โหลดคุณสมบัติจาก jndi.properties และเริ่มต้นอ็อบเจ็กต์ InitialContext

  • ในเมธอด testStatefulEjb () การค้นหา jndi จะดำเนินการด้วยชื่อ - "LibraryStatelessSessionBean / remote" เพื่อรับวัตถุทางธุรกิจระยะไกล (stateful ejb)

  • จากนั้นผู้ใช้จะแสดงส่วนติดต่อผู้ใช้ที่เก็บไลบรารีและระบบจะขอให้ป้อนตัวเลือก

  • หากผู้ใช้ป้อน 1 ระบบจะถามชื่อหนังสือและบันทึกหนังสือโดยใช้วิธี stateless session bean addBook () Session Bean ยังคงมีหนังสืออยู่ในฐานข้อมูลผ่านการเรียก EntityManager

  • หากผู้ใช้ป้อน 2 ระบบจะดึงหนังสือโดยใช้เมธอด stateless session bean getBooks () และออก

  • จากนั้นค้นหา jndi อีกครั้งด้วยชื่อ - "LibraryStatelessSessionBean / remote" เพื่อรับวัตถุทางธุรกิจระยะไกล (EJB ที่มีสถานะ) อีกครั้งและทำรายการหนังสือ

เรียกใช้ไคลเอ็นต์เพื่อเข้าถึง EJB

ค้นหา EJBTester.java ใน project explorer คลิกขวาที่คลาส EJBTester และเลือกrun file.

ตรวจสอบเอาต์พุตต่อไปนี้ในคอนโซล Netbeans

run:
**********************
Welcome to Book Store
**********************
Options 
1. Add Book
2. Exit 
Enter Choice: 1
Enter book name: Learn Testing
**********************
Welcome to Book Store
**********************
Options 
1. Add Book
2. Exit 
Enter Choice: 2
Book(s) entered so far: 1
1. learn Testing
BUILD SUCCESSFUL (total time: 15 seconds)

EJB เป็นส่วนหนึ่งของแอปพลิเคชันระดับองค์กรซึ่งโดยปกติจะขึ้นอยู่กับสภาพแวดล้อมแบบกระจาย ดังนั้นนอกเหนือจากข้อยกเว้นปกติที่สามารถเกิดขึ้นได้แล้วยังมีข้อยกเว้นเช่นการสื่อสารล้มเหลวสิทธิ์ด้านความปลอดภัยเซิร์ฟเวอร์ล่มเป็นต้น

คอนเทนเนอร์ EJB พิจารณาข้อยกเว้นในสองวิธี -

  • Application Exception - หากมีการละเมิดกฎทางธุรกิจหรือมีข้อยกเว้นเกิดขึ้นขณะดำเนินการตามตรรกะทางธุรกิจ

  • System Exception- ข้อยกเว้นใด ๆ ที่ไม่ได้เกิดจากตรรกะทางธุรกิจหรือรหัสธุรกิจ RuntimeException, RemoteException คือ SystemException ตัวอย่างเช่นข้อผิดพลาดระหว่างการค้นหา EJB RuntimeException, RemoteException คือ SystemException

EJB Container จัดการกับข้อยกเว้นอย่างไร

เมื่อไหร่ Application Exceptionเกิดขึ้นคอนเทนเนอร์ EJB สกัดกั้นข้อยกเว้น แต่ส่งคืนสิ่งเดียวกันกับไคลเอ็นต์ตามที่เป็นอยู่ จะไม่ย้อนกลับธุรกรรมเว้นแต่จะระบุไว้ในโค้ดโดยเมธอด EJBContext.setRollBackOnly () EJB Container ไม่รวมข้อยกเว้นในกรณีของ Application Exception

เมื่อไหร่ System Exceptionเกิดขึ้นคอนเทนเนอร์ EJB สกัดกั้นข้อยกเว้นย้อนกลับธุรกรรมและเริ่มงานล้างข้อมูล มันรวมข้อยกเว้นไว้ใน RemoteException และส่งไปยังไคลเอนต์

การจัดการข้อยกเว้นของแอปพลิเคชัน

โดยทั่วไปข้อยกเว้นของแอปพลิเคชันจะถูกส่งไปในเมธอด Session EJB เนื่องจากเป็นวิธีการที่รับผิดชอบในการดำเนินการตามตรรกะทางธุรกิจ ข้อยกเว้นของแอปพลิเคชันควรได้รับการประกาศในประโยค throws ของวิธีการทางธุรกิจและควรถูกโยนทิ้งในกรณีที่ตรรกะทางธุรกิจล้มเหลว

@Stateless
public class LibraryPersistentBean implements LibraryPersistentBeanRemote {
	
   ...

   public List<Book> getBooks() throws NoBookAvailableException {        
      List<Book> books = 
         entityManager.createQuery("From Books").getResultList();
      if(books.size == 0)
		throw NoBookAvailableException
           ("No Book available in library.");
      return books;
   }
   ...
}

การจัดการข้อยกเว้นของระบบ

ข้อยกเว้นของระบบสามารถเกิดขึ้นได้ตลอดเวลาเช่นการค้นหาการตั้งชื่อล้มเหลวข้อผิดพลาด sql เกิดขึ้นขณะดึงข้อมูล ในกรณีเช่นนี้ข้อยกเว้นดังกล่าวควรถูกห่อไว้ภายใต้ EJBException และส่งกลับไปยังไคลเอนต์

@Stateless
public class LibraryPersistentBean implements LibraryPersistentBeanRemote {
	
   ...

   public List<Book> getBooks() {   
      try {
         List<Book> books = 
            entityManager.createQuery("From Books").getResultList();
      } catch (CreateException ce) {
         throw (EJBException) new EJBException(ce).initCause(ce);
      } catch (SqlException se) {
         throw (EJBException) new EJBException(se).initCause(se);    
      }	  
      return books;
   }
   ...
}

ที่ฝั่งไคลเอ็นต์จัดการ EJBException

public class EJBTester {
   private void testEntityEjb() {
   ...
   try{
      LibraryPersistentBeanRemote libraryBean =
      LibraryPersistentBeanRemote)ctx.lookup("LibraryPersistentBean/remote");
   
      List<Book> booksList = libraryBean.getBooks();
   } catch(EJBException e) {
      Exception ne = (Exception) e.getCause();
      if(ne.getClass().getName().equals("SqlException")) {
         System.out.println("Database error: "+ e.getMessage());
      }
   }
   ...
   }
}

EJB 3.0 มีตัวเลือกในการแสดงเซสชัน EJB เป็นบริการเว็บ คำอธิบายประกอบ @WebService ใช้เพื่อทำเครื่องหมายคลาสเป็นจุดสิ้นสุดของบริการเว็บและ @WebMethod ใช้เพื่อแสดงเมธอดเป็นวิธีการเว็บแก่ไคลเอ็นต์

@Stateless
@WebService(serviceName="LibraryService")
public class LibraryPersistentBean implements LibraryPersistentBeanRemote {
	
   ...
   @WebMethod(operationName="getBooks")
   public List<Book> getBooks()  {    
      return entityManager.createQuery("From Books").getResultList();
   }
   ...
}

ตัวอย่างการใช้งาน

ให้เราสร้างแอปพลิเคชันทดสอบ EJB เพื่อทดสอบการรองรับ blob / clob ใน EJB 3.0

ขั้นตอน คำอธิบาย
1

สร้างโปรเจ็กต์ด้วยชื่อ EjbComponent ภายใต้แพ็คเกจ com.tutorialspoint.entity ตามที่อธิบายไว้ในบท EJB - Create Application โปรดใช้โปรเจ็กต์ที่สร้างขึ้นใน EJB - บทความคงอยู่สำหรับบทนี้เพื่อทำความเข้าใจวัตถุก้อน / หยดในแนวคิด EJB

2

สร้าง LibraryPersistentBean.java ภายใต้แพ็คเกจ com.tutorialspoint.stateless ใช้ EJB - บทความคงทนเป็นข้อมูลอ้างอิง เก็บไฟล์ที่เหลือไว้ไม่เปลี่ยนแปลง

3

ทำความสะอาดและสร้างแอปพลิเคชันเพื่อให้แน่ใจว่าตรรกะทางธุรกิจทำงานได้ตามข้อกำหนด

4

สุดท้ายปรับใช้แอปพลิเคชันในรูปแบบของไฟล์ jar บน JBoss Application Server เซิร์ฟเวอร์แอปพลิเคชัน JBoss จะเริ่มทำงานโดยอัตโนมัติหากยังไม่เริ่มทำงาน

LibraryPersistentBean.java

package com.tutorialspoint.stateless;

import com.tutorialspoint.entity.Book;
import java.util.List;
import javax.ejb.Stateless;
import javax.jws.WebMethod;
import javax.jws.WebService;
import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;

@Stateless
@WebService(serviceName="LibraryService")
public class LibraryPersistentBean implements LibraryPersistentBeanRemote {
    
   public LibraryPersistentBean() {
   }

   @PersistenceContext(unitName="EjbComponentPU")
   private EntityManager entityManager;         

   public void addBook(Book book) {
      entityManager.persist(book);
   }    
   
   @WebMethod(operationName="getBooks")
   public List <Book> getBooks() {
      return entityManager.createQuery("From Book").getResultList();
   }
}

เอาต์พุตบันทึกของเซิร์ฟเวอร์แอปพลิเคชัน JBoss

10:51:37,271 INFO  [EJBContainer] STARTED EJB: com.tutorialspoint.stateless.LibraryPersistentBean ejbName: LibraryPersistentBean
10:51:37,287 INFO  [JndiSessionRegistrarBase] Binding the following Entries in Global JNDI:

	LibraryPersistentBean/remote - EJB3.x Default Remote Business Interface
	LibraryPersistentBean/remote-com.tutorialspoint.stateless.LibraryPersistentBeanRemote - EJB3.x Remote Business Interface

10:51:37,349 INFO  [EJBContainer] STARTED EJB: com.tuturialspoint.messagebean.LibraryMessageBean ejbName: BookMessageHandler
10:51:37,443 INFO  [DefaultEndpointRegistry] register: jboss.ws:context=EjbComponent,endpoint=LibraryPersistentBean
10:51:38,191 INFO  [WSDLFilePublisher] WSDL published to: file:/D:/Jboss-5.0.1/server/default/data/wsdl/EjbComponent.jar/
LibraryService3853081455302946642.wsdl

สร้างไคลเอนต์เพื่อเข้าถึง EJB เป็นบริการบนเว็บ

ใน NetBeans IDE เลือก ,File > New Project >เลือกประเภทโครงการภายใต้หมวดหมู่Java, ประเภทโครงการเป็น Java Application. คลิกNext >ปุ่มป้อนชื่อโครงการและที่ตั้ง คลิกFinish >ปุ่ม. เราได้เลือกชื่อเป็น EJBWebServiceClient

คลิกขวาที่ชื่อโครงการในหน้าต่าง Project explorer เลือกNew > WebService Client.

เพิ่ม LibraryPersistentBean ของโครงการคอมโพเนนต์ EJB ที่สร้างขึ้นก่อนหน้านี้ภายใต้ WSDL และ Client Location โดยใช้ Add Project ปุ่มใน compile แท็บ

คลิกปุ่มเสร็จสิ้น ตรวจสอบโครงสร้างต่อไปนี้ในตัวสำรวจโครงการ

สร้าง EJBWebServiceClient.java

package ejbwebserviceclient;

public class EJBWebServiceClient {
   public static void main(String[] args) {   
   }
}

เลือก Web Service getBooks web method ดังแสดงในรูปด้านล่างและลากไปยังหน้าต่าง code ของ EJBWebServiceClient

คุณจะเห็นผลลัพธ์คล้ายกับที่แสดงด้านล่าง

อัปเดตรหัส EJBWebServiceClient เพื่อใช้วิธีนี้

package ejbwebserviceclient;

public class EJBWebServiceClient {

   public static void main(String[] args) {
      for(com.tutorialspoint.stateless.Book book:getBooks()) {
         System.out.println(book.getName());
      }       
   }

   private static java.util.List
   <com.tutorialspoint.stateless.Book> getBooks() {
      com.tutorialspoint.stateless.LibraryService service = 
         new com.tutorialspoint.stateless.LibraryService();
      com.tutorialspoint.stateless.LibraryPersistentBean port = 
         service.getLibraryPersistentBeanPort();
      return port.getBooks();
   }      
}

เรียกใช้ไคลเอ็นต์

คลิกขวาที่ชื่อโครงการในหน้าต่าง Project explorer เลือกRun. Netbeans จะสร้างไคลเอนต์และเรียกใช้ ตรวจสอบผลลัพธ์ต่อไปนี้

ant -f D:\\SVN\\EJBWebServiceClient run
init:
Deleting: D:\SVN\EJBWebServiceClient\build\built-jar.properties
deps-jar:
Updating property file: D:\SVN\EJBWebServiceClient\build\built-jar.properties
wsimport-init:
wsimport-client-LibraryPersistentBean:
files are up to date
classLoader = java.net.URLClassLoader@4ce46c
SharedSecrets.getJavaNetAccess()=java.net.URLClassLoader$7@182cdac
wsimport-client-generate:
Compiling 1 source file to D:\SVN\EJBWebServiceClient\build\classes
compile:
run:
learn java
Learn Spring
learn JSF
Learn HTML
Learn JBoss
Learn EJB
Learn Hibernate
Learn IBatis
Times Now
learn html5
Learn images
Learn Testing
Forbes
test1
BUILD SUCCESSFUL (total time: 1 second)

ข้อกำหนดของแอพพลิเคชั่นบรรจุภัณฑ์ที่ใช้ EJB 3.0 นั้นคล้ายคลึงกับแพลตฟอร์ม J2EE คอมโพเนนต์ EJB ถูกบรรจุลงในโมดูลเป็นไฟล์ jar และถูกบรรจุลงในไฟล์เก็บถาวรขององค์กรแอปพลิเคชันเป็นไฟล์หู

แอปพลิเคชันระดับองค์กรมีสามองค์ประกอบหลัก ๆ ได้แก่

  • jar - Java Application aRchive ที่มีโมดูล EJB โมดูลไคลเอนต์ EJB และโมดูลยูทิลิตี้

  • war - Web Application aRchive ที่มีโมดูลเว็บ

  • ear - แอปพลิเคชันสำหรับองค์กร aRchive ที่มีขวดโหลและโมดูลสงคราม

ใน NetBeans การสร้างพัฒนาแพ็กเกจและปรับใช้แอปพลิเคชัน J2EE นั้นง่ายมาก

ใน NetBeans IDE เลือกFile > New Project >เลือกประเภทโครงการภายใต้หมวดหมู่Java EE, ประเภทโครงการเป็น Enterprise Application. คลิกNext >ปุ่ม. ป้อนชื่อโครงการและที่ตั้ง คลิกFinish >ปุ่ม. เราได้เลือกชื่อเป็น EnterpriseApplicaton

เลือกเซิร์ฟเวอร์และการตั้งค่า เก็บไว้Create EJB Module และ Create Web Application Moduleตรวจสอบด้วยชื่อเริ่มต้นที่ระบุ คลิกปุ่มเสร็จสิ้น NetBeans จะสร้างโครงสร้างต่อไปนี้ในหน้าต่างโครงการ

คลิกขวาที่โครงการ Enterprise Application ในตัวสำรวจโครงการและเลือกสร้าง

ant -f D:\\SVN\\EnterpriseApplication dist
pre-init:
init-private:
init-userdir:
init-user:
init-project:
do-init:
post-init:
init-check:
init:
deps-jar:
deps-j2ee-archive:
EnterpriseApplication-ejb.init:
EnterpriseApplication-ejb.deps-jar:
EnterpriseApplication-ejb.compile:
EnterpriseApplication-ejb.library-inclusion-in-manifest:

Building jar: D:\SVN\EnterpriseApplication\EnterpriseApplication-ejb\dist\EnterpriseApplication-ejb.jar

EnterpriseApplication-ejb.dist-ear:
EnterpriseApplication-war.init:
EnterpriseApplication-war.deps-module-jar:
EnterpriseApplication-war.deps-ear-jar:
EnterpriseApplication-ejb.init:
EnterpriseApplication-ejb.deps-jar:
EnterpriseApplication-ejb.compile:
EnterpriseApplication-ejb.library-inclusion-in-manifest:
EnterpriseApplication-ejb.dist-ear:
EnterpriseApplication-war.deps-jar:
EnterpriseApplication-war.library-inclusion-in-archive:
EnterpriseApplication-war.library-inclusion-in-manifest:
EnterpriseApplication-war.compile:
EnterpriseApplication-war.compile-jsps:
EnterpriseApplication-war.do-ear-dist:

Building jar: D:\SVN\EnterpriseApplication\EnterpriseApplication-war\dist\EnterpriseApplication-war.war

EnterpriseApplication-war.dist-ear:
pre-pre-compile:
pre-compile:
Copying 1 file to D:\SVN\EnterpriseApplication\build
Copying 1 file to D:\SVN\EnterpriseApplication\build
do-compile:
post-compile:
compile:
pre-dist:
do-dist-without-manifest:
do-dist-with-manifest:

Building jar: D:\SVN\EnterpriseApplication\dist\EnterpriseApplication.ear

post-dist:
dist:
BUILD SUCCESSFUL (total time: 1 second)

ที่นี่คุณจะเห็นว่า Netbeans เตรียม Jar ก่อนจากนั้นจึง War และท้ายที่สุดไฟล์ ear ที่มี jar และ war คือไฟล์ ไฟล์ jar สงครามและหูแต่ละอันมีไฟล์meta-inf โฟลเดอร์ที่มีข้อมูลเมตาตามข้อกำหนด J2EE