在详细讨论这个问题之前,让我们再来回顾一下Web服务的定义。为了解释Web服务定义语言(WSDL)的规范,Web服务由一组相关的网络端点(地址)和关联的消息组成。可以推测,当一个适当的消息发送到端点时,一些有用的操作就会在端点触发。
Web服务调用消息一般根据简单对象访问协议(SOAP)来格式化。SOAP规范的早期版本将SOAP绑定到超文本传输协议(HTTP)中,并且现今存在的大多数Web服务实现都偏向于HTTP。但是Web服务理论上应该可以通过任何"标准的"Internet协议得到。
本文回答了这样一个问题:"如何通过简单邮件传输协议(SMTP)和Web服务进行通信?"
尽管SMTP仅有短短20年的历史,但在Internet上从点到点传输的大部分电子邮件流依然是通过这个协议发送的。

WebLogic Workshop 7.0没有把内置的SMTP支持当作Web服务传输协议。不过,它把支持Java 消息服务(JMS)的协议当作Web服务传输协议。因此在这个例子中,我将安装自己的邮件服务器(使用Apache Jakarta project的James,)并且将传入邮件消息的消息内容转发给WebLogicWorkshop内置的JMS队列jws.queue。如果一个格式正确的消息被发送给jws.queue,那么WebLogic Workshop运行时间将会把它分派给Web服务对象,就像它是通过HTTP到达的一样。
我的例子中Web服务对象是EmailService.jws,它展示了helloAsync操作。helloAsync操作用JavaMail API发送一个在WebLogic使用JavaMail的响应消息。
记住,你是通过发送XML(一般是SOAP)消息和Web服务进行通信的,本例中的作业就是把包含收件电子邮件的XML消息递送给目标Web服务。
传入邮件路由选择
正如前所述,我使用来自Apache Jakarta项目的James邮件服务器接收传入的电子邮件消息。我选择James是因为它的安装和配置都出奇的简单。James邮件服务器很容易通过mailets扩充,mails是相对小且简单的Java类,它处理由James接收的电子邮件消息。在James的配置文件中创建一条传送消息的mailets管道。如果消息符合mailets的匹配规则,那么消息就传递到mailet服务方法进行处理。
和James一起安装的默认配置文件通过若干反垃圾邮件(anti-spam)mailets来路由消息,以免James服务器成为一个开放中继器(open relay)。就像任何典型的邮件服务器一样,最后,消息存放在目标用户的邮箱中。我修改了这个文件配置使之不能存放消息,而是通过自定义的mailets(本人写的,权称之为ForwardToJMSQueue)路由所有消息。
下面是ForwardToJMSQueue mailet的代码:
package com.bea.mailet;
import weblogic.jndi.Environment;
import org.apache.mailet.GenericMailet;
import org.apache.mailet.Mail;
import javax.mail.MessagingException;
import javax.mail.internet.MimeMessage;
import javax.naming.Context;
import javax.naming.InitialContext;
import javax.jms.QueueConnectionFactory;
import javax.jms.QueueConnection;
import javax.jms.QueueSession;
import javax.jms.Queue;
import javax.jms.QueueSender;
import javax.jms.TextMessage;
import java.util.*;
public class ForwardToJMSQueue extends GenericMailet {
public void service(Mail mail)
{
try
{
// Use the WebLogic convenience Environment object to
// create an InitialContext
Environment env = new Environment();
Context ctx = env.getInitialContext();
// get the WebLogic Workshop QueueConnectionFactory
QueueConnectionFactory factory =
(QueueConnectionFactory)ctx.lookup
("weblogic.jws.jms.QueueConnectionFactory");
QueueConnection conn = factory.createQueueConnection();
QueueSession session = conn.createQueueSession(false, 0);
// look up the queue that is the destination for JWS requests
Queue queue = (Queue)ctx.lookup("jws.queue");
QueueSender sender = session.createSender(queue);
// get the content of the arriving e-mail message
MimeMessage mimeMsg = mail.getMessage();
String emailMsgStr = (String)mimeMsg.getContent();
// create a new TextMessage to send to the JWS JMS queue
TextMessage textMessage = session.createTextMessage(emailMsgStr);
// to target a particular JWS, pass its path as the value
// of the "URI" text property on the JMS message. In the
// scheme used by this mailet, the path to the JWS must
// arrive as the Subject: of the message.
textMessage.setStringProperty("URI", mimeMsg.getSubject());
// send the message
sender.send(textMessage);
// clean up
session.close();
conn.close();
}
catch(java.lang.Exception ex)
{
System.out.println("Exception in ForwardToJMSQueue mailet:");
ex.printStackTrace();
}
}
}
