原文連結:jboss7部署MDB
原文是針對JBoss7的,配置檔案已經不适用,最新的Wildfly10使用 standalone-ful.xml 根據原文稍微修改下代碼就可以
EJB的第二種類型:
Message Driven Bean,MDB:用于Java EE應用程式中各元件之間的異步通信,可用于接收與Java消息傳遞服務(JMS)相容的消息,并根據接收消息的内容采取一些操作。
消息驅動Bean(MDB)使Java EE應用程式異步處理消息。一旦部署在應用程式伺服器上,它将監聽JMS消息,并為每個收到的消息執行一個操作(調用MDB的onMessage方法)。 MDB為應用程式開發提供事件驅動的松散耦合模型。 MDB不會被注入或從用戶端代碼中調用,但會由收到的消息觸發。
MDB是無狀态的,不與客戶保持任何對話狀态。應用程式伺服器維護一個MDB池,并通過配置設定和傳回池中的執行個體并管理它們的生命周期。他們也可以參與事務處理,并且應用程式伺服器根據消息處理的結果負責消息重新傳送和消息接收确認。
有許多可以使用MDB的用例。最流行的是解耦系統,并防止它們的API通過直接調用而被緊密耦合。相反,兩個系統可以通過以異步方式傳遞消息來進行通信,這確定了兩個系統可以獨立進化而不會互相影響。
原文連結:https://cloud.tencent.com/developer/article/1151941
一、standalone-ful.xml
1、Wildfly啟動預設使用的是 standalone.xml ,但是這個版本的standalone.xml 中沒有MDB的配置,但是standalone-ful.xml 中有
2、如果根據原文連結部落格的修改standalone.xml,會報各種錯誤,因為版本不一緻。
3、還是預設使用 standalone.xml 這裡不修改, 直接copy standalone-ful.xml到 standalone.xml
檔案路徑:wildfly-10.1.0.Final\standalone\configuration
二、Creating New EJB Project
1、Eclipse建立EJB FirstMDBProject
2、Creating object message class
Employee 作為消息傳遞的實體
package com.theopentutorials.mdb.to;
import java.io.Serializable;
public class Employee implements Serializable {
private int id;
private String name;
private String designation;
private double salary;
public Employee() {
}
public Employee(int id, String name, String designation, double salary) {
this.id = id;
this.name = name;
this.designation = designation;
this.salary = salary;
}
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 getDesignation() {
return designation;
}
public void setDesignation(String designation) {
this.designation = designation;
}
public double getSalary() {
return salary;
}
public void setSalary(double salary) {
this.salary = salary;
}
@Override
public String toString() {
return "Employee [id=" + id + ", name=" + name + ", designation=" + designation + ", salary=" + salary + "]";
}
}
三、Creating Message Driven Bean Consumer
1、ejbModule -> New -> Message-Driven Bean (EJB 3.x)
- Enter the Java package name as com.theopentutorials.mdb
- Enter the Class name as QueueListenerMDB
- Select the Destination type as Queue
- Click “Finish
2、最終的項目結構:
3、自動生成 QueueListenerMDB.java
package com.theopentutorials.mdb;
import java.util.Date;
import javax.ejb.ActivationConfigProperty;
import javax.ejb.MessageDriven;
import javax.jms.JMSException;
import javax.jms.Message;
import javax.jms.MessageListener;
import javax.jms.ObjectMessage;
import javax.jms.TextMessage;
import com.theopentutorials.mdb.to.Employee;
/**
* Message-Driven Bean implementation class for: QueueListenerMDB
*/
@MessageDriven(activationConfig = {
@ActivationConfigProperty(propertyName = "destinationType", propertyValue = "javax.jms.Queue"),
@ActivationConfigProperty(propertyName = "destination", propertyValue = "java:/jms/queue/ExpiryQueue") })
public class QueueListenerMDB implements MessageListener {
/**
* Default constructor.
*/
public QueueListenerMDB() {
}
/**
* @see MessageListener#onMessage(Message)
*/
public void onMessage(Message message) {
try {
if (message instanceof TextMessage) {
System.out.println("Queue: I received a TextMessage at " + new Date());
TextMessage msg = (TextMessage) message;
System.out.println("Message is : " + msg.getText());
} else if (message instanceof ObjectMessage) {
System.out.println("Queue: I received an ObjectMessage at " + new Date());
ObjectMessage msg = (ObjectMessage) message;
Employee employee = (Employee) msg.getObject();
System.out.println("Employee Details: ");
System.out.println(employee.getId());
System.out.println(employee.getName());
System.out.println(employee.getDesignation());
System.out.println(employee.getSalary());
} else {
System.out.println("Not a valid message for this Queue MDB");
}
} catch (JMSException e) {
e.printStackTrace();
}
}
}
第二個@ActivationConfigProperty 沒有需要自己添加上
wildfly-10.1.0.Final\standalone\configuration 中的 standalone.xml 沒有MDB相關配置,需要拷貝 standalone-ful.xml
然後和之前修改的standalone.xml同步
- The activationConfig property of @MessageDriven is an array of ActivationConfigProperty and it should specify the destinationType (Queue or Topic) and destination (Queue/Topic’s JNDI name).
檢視自己的 standalone.xml(也就是standalone-ful.xml)發現 Queue’s JNDI name :java:/jms/queue/ExpiryQueue
在 @ActivationConfigProperty 中進行配置
四、Creating JMS client (Dynamic Web Project)
1、就是建立Web工程 MDBWebClient
2、Creating Servlet class
ServletMessageProducer.class
3、将 EJB工程中的實體 Employee 打成jar 放到 WEB工程的 WebContent-WEB-INF-lib 下 自動build
這裡用到JMS傳遞消息的第二種類型:ObjectMessage
4、Queue查找JNDI名字,和配置檔案中的名字對應起來:java:/jms/queue/ExpiryQueue
package com.theopentutorials.servlets;
import java.io.IOException;
import java.io.PrintWriter;
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.jms.TextMessage;
import javax.naming.Context;
import javax.naming.InitialContext;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import com.theopentutorials.mdb.to.Employee;
@WebServlet("/ServletMessageProducer")
public class ServletMessageProducer extends HttpServlet {
private static final long serialVersionUID = 1L;
public ServletMessageProducer() {
super();
}
protected void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
// response.getWriter().append("Served at: ").append(request.getContextPath());
// final String QUEUE_LOOKUP = "queue/MyQueue";
final String QUEUE_LOOKUP = "java:/jms/queue/ExpiryQueue";
final String CONNECTION_FACTORY = "ConnectionFactory";
PrintWriter out = response.getWriter();
try {
Context context = new InitialContext();
QueueConnectionFactory factory = (QueueConnectionFactory) context.lookup(CONNECTION_FACTORY);
QueueConnection connection = factory.createQueueConnection();
QueueSession session = connection.createQueueSession(false, QueueSession.AUTO_ACKNOWLEDGE);
Queue queue = (Queue) context.lookup(QUEUE_LOOKUP);
QueueSender sender = session.createSender(queue);
// 1. Sending TextMessage to the Queue
TextMessage message = session.createTextMessage();
message.setText("Hello EJB3 MDB Queue!!!");
sender.send(message);
out.println("1. Sent TextMessage to the Queue");
//2. Sending ObjectMessage to the Queue
ObjectMessage objMsg = session.createObjectMessage();
Employee employee = new Employee();
employee.setId(2018);
employee.setName("wls");
employee.setDesignation("CTO");
employee.setSalary(10000);
objMsg.setObject(employee);
sender.send(objMsg);
out.println("2. Sent ObjectMessage to the Queue");
session.close();
} catch (Exception e) {
e.printStackTrace();
}
}
protected void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
doGet(request, response);
}
}
五、Deploying Dynamic Web Project 、EJB project
1、在Wildfly部署 EJB。WEB
2、浏覽器通路: http://localhost:8081/MDBWebClient/ServletMessageProducer
3、console