`
bh三少
  • 浏览: 102058 次
  • 性别: Icon_minigender_1
  • 来自: 北海
社区版块
存档分类
最新评论

EJB系统使用JMS异步发送邮件

阅读更多

EJB中有三种Bean,EntityBean,SessionBean,MessageBean,其中MessageBean就是用来发送消息的。
服务器:JBoss 4.2

EJB中支持两种类型的消息,一种是Topic,一种是Queue。
Topic:基于发布/订阅的方式,允许有多个接受者,消息生产者将消息发送到主题上,接受者必须先订阅该主题。
Queue:点对点的方式,只能被一个接受者接受一次,消息生产者把消息发送到队列中,不需订阅。

要在JBoss中使用JMS,需要配置一些文件
1.%JBOSS_HOME%\server\default\deploy 下mail-service.xml,该文件用于配置发送email的一些参数(例子中使用gmail服务器)

<?xml version="1.0" encoding="UTF-8"?>
<server>
  <mbean code="org.jboss.mail.MailService"
         name="jboss:service=Mail">
    <attribute name="JNDIName">java:/Mail</attribute>
    <attribute name="User">zoucailong</attribute>
    <attribute name="Password">******</attribute>
    <attribute name="Configuration">
      <!-- A test configuration -->
      <configuration>
        <!-- Change to your mail server prototocol -->
        <property name="mail.store.protocol" value="pop3"/>
        <property name="mail.transport.protocol" value="smtp"/>
        <!-- Change to the user who will receive mail  -->
        <property name="mail.user" value="zoucailong"/>
        <!-- Change to the mail server  -->
        <property name="mail.pop3.host" value="pop3.gmail.com"/>
        <!-- Change to the SMTP gateway server -->
        <property name="mail.smtp.host" value="smtp.gmail.com"/>
		<property name="mail.smtp.socketFactory.class" value="javax.net.ssl.SSLSocketFactory"/>
		<property name="mail.smtp.socketFactory.fallback" value="false"/>
		<property name="mail.smtp.auth" value="true"/>        
        <!-- The mail server port -->
        <property name="mail.smtp.port" value="465"/>        
        <!-- Change to the address mail will be from  -->
        <property name="mail.from" value="zoucailong@gmail.com"/>
        <!-- Enable debugging output from the javamail classes -->
        <property name="mail.debug" value="false"/>
      </configuration>
    </attribute>
    <depends>jboss:service=Naming</depends>
  </mbean>
</server>

如果邮件发送不成功,可以把"mail.debug"的值改为true调试。

2.%JBOSS_HOME%\server\default\deploy\jms 下jbossmq-destinations-service.xml,该文件用于配置Topic和Queue

<mbean code="org.jboss.mq.server.jmx.Topic"
	 name="jboss.mq.destination:service=Topic,name=testTopic">
    <depends optional-attribute-name="DestinationManager">jboss.mq:service=DestinationManager</depends>
    <depends optional-attribute-name="SecurityManager">jboss.mq:service=SecurityManager</depends>
    <attribute name="SecurityConf">
      <security>
        <role name="guest" read="true" write="true"/>
        <role name="publisher" read="true" write="true" create="false"/>
        <role name="durpublisher" read="true" write="true" create="true"/>
      </security>
    </attribute>
  </mbean>

   <mbean code="org.jboss.mq.server.jmx.Queue"
	 name="jboss.mq.destination:service=Queue,name=fmQueue">
    <depends optional-attribute-name="DestinationManager">jboss.mq:service=DestinationManager</depends>
    <depends optional-attribute-name="SecurityManager">jboss.mq:service=SecurityManager</depends>
    <attribute name="MessageCounterHistoryDayLimit">-1</attribute>
    <attribute name="SecurityConf">
      <security>
        <role name="guest" read="true" write="true"/>
        <role name="publisher" read="true" write="true" create="false"/>
        <role name="noacc" read="false" write="false" create="false"/>
      </security>
    </attribute>
  </mbean>

启动JBoss,可以在控制台看到自己配置的Topic或Queue的名字。

 

定义一个实体,用来封装发送邮件所需要的参数,包括接收人邮件地址、主题、内容、附件地址等。

import java.io.Serializable;
import java.util.Date;

public class EmailEntity implements Serializable {

    private static final long serialVersionUID = 3436776941158302904L;
    private String from; 
    private String to;  
    private String subject;   
    private String content;
    private String multiPartFile;
    private Date sendDate;
    
    public EmailEntity() {
        
    }
    public EmailEntity(String to, String subject, String content, String multiPartFile) {
        this.to = to;
        this.subject = subject;
        this.content = content;
        this.multiPartFile = multiPartFile;
    }
    public String getFrom() {
        return from;
    }
    public void setFrom(String from) {
        this.from = from;
    }
    public String getTo() {
        return to;
    }
    public void setTo(String to) {
        this.to = to;
    }
    public String getSubject() {
        return subject;
    }
    public void setSubject(String subject) {
        this.subject = subject;
    }
    public String getContent() {
        return content;
    }
    public void setContent(String content) {
        this.content = content;
    }
    public String getMultiPartFile() {
        return multiPartFile;
    }
    public void setMultiPartFile(String multiPartFile) {
        this.multiPartFile = multiPartFile;
    }
    public Date getSendDate() {
        return sendDate;
    }
    public void setSendDate(Date sendDate) {
        this.sendDate = sendDate;
    }
}

 

 

写一个Message Producer,一个普通的Java类,在这个类中使用到JMS的API

import java.util.Properties;
import javax.jms.JMSException;
import javax.jms.MessageProducer;
import javax.jms.ObjectMessage;
import javax.jms.Queue;
import javax.jms.QueueConnection;
import javax.jms.QueueConnectionFactory;
import javax.jms.QueueSession;
import javax.jms.Session;
import javax.naming.Context;
import javax.naming.InitialContext;
import javax.naming.NamingException;
import org.apache.log4j.Logger;

public class MsgProducerService {
    
    private static Logger logger = Logger.getLogger(MsgProducerService.class);
    
    private static InitialContext context;
    private static Queue queue;
    private static QueueConnectionFactory connectionFactory;
    
    private static InitialContext getInitialContext() throws NamingException {
        if(context == null) {
            Properties env = new Properties();
            env.setProperty(Context.INITIAL_CONTEXT_FACTORY, "org.jnp.interfaces.NamingContextFactory");
            env.setProperty(Context.PROVIDER_URL, "localhost");
            context = new InitialContext(env);
        }
        return context;
    }
    
    static {
           try {
            connectionFactory = (QueueConnectionFactory) getInitialContext().lookup("ConnectionFactory");
            queue = (Queue) getInitialContext().lookup("queue/fmQueue");
        } catch (NamingException e) {
            e.printStackTrace();
        }
    }
    
    public static void sendMail(EmailEntity emailEntity) {
        
        QueueConnection connection = null;
        QueueSession session = null;
        MessageProducer producer;
        
        try {
            connection = connectionFactory.createQueueConnection();
            session = connection.createQueueSession(false, Session.AUTO_ACKNOWLEDGE);
            producer = session.createProducer(queue);
            ObjectMessage msg = session.createObjectMessage();
            msg.setObject(emailEntity);
            producer.send(msg);
        } catch (JMSException e) {
            logger.error("Send email error:"+e);
            e.printStackTrace();
        } finally {
            try {
                if(session != null)
                    session.close();
                if(connection != null)
                    connection.close();
            } catch (JMSException e) {
                    e.printStackTrace();
            }
        }
    }
}

以上代码中,ObjectMessage根据你的消息类型而定,有
StreamMessage:一种主体中包含Java基本值流的消息。其填充和读取均按顺序进行。
MapMessage:一种主体中包含一组名-值对的消息。(没有定义条目顺序)
TextMessage:一种主体中包含Java字符串的消息(例如:XML消息)
ObjectMessage:一种主体中包含序列化Java对象的消息。
BytesMessage:一种主体中包含连续字节流的消息。

 

下面定义一个消息接受者,该类实现MessageListener接口,自动监听消息的状态,当有消息到达时,就会触发onMessage方法

import java.io.File;
import java.util.Date;
import javax.activation.DataHandler;
import javax.activation.FileDataSource;
import javax.ejb.ActivationConfigProperty;
import javax.ejb.MessageDriven;
import javax.jms.MessageListener;
import javax.jms.ObjectMessage;
import javax.mail.Message;
import javax.mail.Multipart;
import javax.mail.Session;
import javax.mail.Transport;
import javax.mail.internet.InternetAddress;
import javax.mail.internet.MimeBodyPart;
import javax.mail.internet.MimeMessage;
import javax.mail.internet.MimeMultipart;
import javax.naming.Context;
import javax.naming.InitialContext;

//指定destination的类型和名字,以下用的是Queue,用到上面的配置文件中定义的fmQueue
@MessageDriven(activationConfig ={
        @ActivationConfigProperty(propertyName = "destinationType",
                propertyValue = "javax.jms.Queue"),
        @ActivationConfigProperty(propertyName = "destination",
                propertyValue = "queue/fmQueue")
})
public class EmailBean implements MessageListener {

    @Override
    public void onMessage(javax.jms.Message msg) {
        try {
            if(msg != null && msg instanceof ObjectMessage) {
                ObjectMessage objMsg = (ObjectMessage)msg;
                EmailEntity emailEntity = (EmailEntity) objMsg.getObject();
                sendMail(emailEntity);
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
    
    
    //发送邮件的方法
    private void sendMail(EmailEntity emailEntity) throws Exception {
        if(emailEntity == null)
            return;
        
        Context context = new InitialContext();
        Session session = (Session) context.lookup("java:/Mail");
        MimeMessage msg = new MimeMessage(session);
        msg.setFrom();
        
        if(emailEntity.getTo() != null && emailEntity.getTo().trim().length() > 0) {
            String[] toArr = emailEntity.getTo().split(",");
            if(toArr.length > 0) {
                InternetAddress[] addressArr = new InternetAddress[toArr.length];
                for(int i = 0; i < toArr.length; i++) {
                    addressArr[i] = new InternetAddress(toArr[i]);
                }
                msg.addRecipients(Message.RecipientType.TO, addressArr);
            }
        }
        if(emailEntity.getSubject() != null)
            msg.setSubject(emailEntity.getSubject(), "UTF-8");
        
        if(emailEntity.getMultiPartFile() != null) {
            File file = new File(emailEntity.getMultiPartFile());
            if(file.exists()) {
		//添加附件
                Multipart multipart = new MimeMultipart();
                MimeBodyPart bodyPart = new MimeBodyPart();
                FileDataSource fds = new FileDataSource(emailEntity.getMultiPartFile());
                bodyPart.setDataHandler(new DataHandler(fds));
                bodyPart.setFileName(fds.getName());
                multipart.addBodyPart(bodyPart);
                
                if(emailEntity.getContent() != null) {
                    MimeBodyPart bodyPartText = new MimeBodyPart();
                    bodyPartText.setText(emailEntity.getContent(), "UTF-8");
                    multipart.addBodyPart(bodyPartText);
                }
                msg.setContent(multipart);
            } else
                return;
        }
        
        msg.setSentDate(new Date());
        msg.saveChanges();
        Transport.send(msg, msg.getRecipients(Message.RecipientType.TO));
    }
}

这样就可以实现邮件的异步发送了。

分享到:
评论

相关推荐

    JMS异步通信

    Java消息服务(JMS)是Java平台上用于异步通信的标准API。它允许应用程序通过消息传递在分布式系统中进行通信,从而实现解耦和提高...通过截图和教程,WSAD提供了一个全面的平台,帮助开发者理解和实现JMS异步通信。

    EJB TO JMS

    JMS允许应用程序通过消息中间件进行异步通信,从而提高系统的可扩展性和可靠性。在本讨论中,我们将关注如何从EJB(Enterprise JavaBeans)向JMS Topic发布消息。 首先,EJB是Java平台上的一个组件模型,用于构建可...

    EJB系统开发实战

    - **消息驱动Bean(Message-Driven Beans)**:用于处理JMS(Java Message Service)消息,实现异步处理。 2. **EJB容器服务** - **事务管理**:EJB容器自动管理事务,确保数据一致性。 - **安全性**:提供用户...

    EJB javaEE5 JMS1.1 JSP2.1规范中文版

    JMS提供了异步通信的能力,允许应用程序在不阻塞的情况下交换数据,是企业级系统中实现解耦和可靠消息传递的重要工具。 6. **JSP2.1规范**是JavaServer Pages的版本,是一种用于创建动态网页的技术。JSP2.1引入了...

    WSAD环境下JMS异步通信全攻略

     3.1 使用JMS QueueConnection对象  3.2 处理回退事件  3.3 关闭JMS对象  3.4 接收消息  3.5 消息驱动的Bean  3.6 消息持久化  3.7 消息选择器 四、JMS Pub/Sub编程 五、二阶段提交的事务 ...

    EJB系统开发实战录(完整版)

    **EJB系统开发实战录**是一本专注于企业级JavaBean(EJB)技术的实践教程,全面涵盖了EJB从基础到高级的各个层面。EJB是Java平台企业版(Java EE)的重要组成部分,用于构建可扩展、可靠且安全的企业级应用。这本书...

    EJB 系统开发实战录

    9. **JMS和Message-Driven Beans**:JMS是Java平台上的消息中间件标准,消息驱动bean是EJB中的特殊类型,用于异步处理来自JMS队列或主题的消息,提高了系统的响应性和可扩展性。 10. **部署描述符**:EJB的部署描述...

    pafa中使用ejb

    2. **消息驱动bean(Message-Driven Beans,MDB)**:这些bean用于处理JMS(Java Message Service)消息,使得应用能够实现异步通信。它们通常用于解耦发送和接收消息的系统。 3. **实体bean(Entity Beans)**:在...

    JMS 介绍及其在 EJB 2.0 中的用法

    总的来说,JMS在EJB 2.0中的使用扩展了企业级Java应用的能力,使得应用程序可以更有效地处理异步通信和解耦。通过MessageDrivenBean,开发者能够构建出更健壮、可扩展的系统,而不需要直接处理底层的消息传递细节。

    ejb网上银行系统

    【ejb网上银行系统】是一个基于EJB(Enterprise JavaBeans)技术、J2EE(Java 2 Platform, Enterprise Edition)框架开发的项目,主要用于模拟实际银行的在线服务,包括用户管理、账户操作等功能。该系统提供了友好...

    jms-ejb3 source code

    JMS是Java平台的标准API,用于在分布式环境中发送和接收异步消息。它提供了一种平台无关的方式来处理消息,使得应用可以进行异步通信,提高系统的响应速度和容错能力。JMS支持两种消息模式:点对点(Point-to-Point...

    EJB系统开发实战录.pdf

    在该系统中,可能使用会话Bean来处理用户的注册请求,实体Bean来存储和检索参会者信息,消息驱动Bean可能用于处理后台通知或确认邮件的发送。 1. 会话Bean:创建一个无状态会话Bean处理注册请求,验证用户输入,与...

    基于Struts+EJB购书系统

    Message-Driven Beans则用于处理JMS(Java Message Service)消息,可能在订单确认或库存更新等异步场景中发挥作用。 **购书系统中的集成应用** 在基于Struts+EJB的购书系统中,Struts主要负责用户交互和应用流程...

    ejb实现的超市管理系统

    3. **消息驱动bean(Message-Driven Beans,MDB)**:虽然在这个描述中未明确提及,但若系统涉及异步处理,如订单确认邮件发送,可能使用了MDB来监听消息队列,从而解耦业务处理。 ### 系统架构 该超市管理系统由...

    EJB系统开发实战录

    **EJB系统开发实战录** 企业级JavaBean(Enterprise JavaBeans,简称EJB)是Java平台上用于构建可扩展、安全且事务处理能力强的企业级应用程序的核心技术。EJB系统开发实战录是一本深入探讨EJB技术及其在实际项目中...

    EJB使用范例

    3. **消息驱动bean**:消息驱动bean是处理JMS(Java Message Service)消息的bean,通常用于异步处理。它们接收消息,执行相应的业务逻辑,然后发布响应或处理结果,从而解耦发送和接收操作,提高系统的响应性和可...

    EJB消息驱动bean Demo

    总结一下,EJB消息驱动bean是Java EE应用中处理异步消息的核心组件,与JMS配合,可以实现高效、解耦的系统通信。"EJB消息驱动bean Demo"为你提供了一个实际操作的例子,通过它你可以学习如何设置和使用MDB,以及如何...

Global site tag (gtag.js) - Google Analytics