[SOLUTION]
I am including the full solution because I think this is the type of
thing everybody wants....
#####################################################################
1. Create your service
/*
* NOIMailService.java
*
* Created on April 2, 2003, 5:19 PM
*/
package com.noi.mailservlet.web.services;
import javax.activation.*;
import java.util.*;
import javax.ejb.*;
import javax.mail.*;
import javax.mail.internet.*;
import javax.mail.search.*;
import java.io.*;
/**
*
* @author clay
*/
public class NOIMailService {
/** Holds value of property username. */
private String username;
/** Holds value of property password. */
private String password;
/** Holds value of property hostname. */
private String hostname;
private boolean connected;
/** Holds value of property protocol. */
private String protocol;
private static final String loginmbox = "INBOX";
private Store store;
private Session session;
private URLName url;
/** Creates a new instance of NOIMailService */
public NOIMailService() {
this.connected = false;
this.protocol = "imap";
}
public boolean login(String protocol, String username, String
password, String hostname)
{
this.protocol = protocol;
this.username = username;
this.password = password;
this.hostname = hostname;
try{
url = new URLName(
this.protocol,
this.hostname,
-1,
this.loginmbox,
this.username,
this.password);
Properties props = System.getProperties();
if (hostname != null)
props.put("mail.smtp.host", this.hostname);
else if (props.getProperty("mail.smtp.host") == null)
props.put("mail.smtp.host", "localhost");
this.session = Session.getDefaultInstance(props, null);
this.session.setDebug(true);
PasswordAuthentication pw = new
PasswordAuthentication(url.getUsername(), this.url.getPassword());
this.session.setPasswordAuthentication(url, pw);
this.store = this.session.getStore(url);
this.store.connect();
this.connected = true;
return this.connected;
}
catch(Exception e)
{
this.connected = false;
return this.connected;
}
}
public boolean isConnected()
{
return this.connected;
}
public boolean sendStatelessMessage(String protocol, String
username, String password, String hostname, String to, String cc, String
bcc, String subject, String body)
{
if(this.login(protocol, username, password, hostname))
{
try {
Message msg = new MimeMessage(this.session);
//to
InternetAddress[] toAddrs = null;
if ((to != null) && !to.equals("")) {
toAddrs = InternetAddress.parse(to, false);
msg.setRecipients(Message.RecipientType.TO,
toAddrs);
}
else
return false;
//sent date
msg.setSentDate(Calendar.getInstance().getTime());
//from
String fromAddress = url.getUsername() +
"@"+url.getHost();
msg.setFrom(new InternetAddress(fromAddress));
//cc
InternetAddress[] ccAddrs = null;
if ((cc != null) && !cc.equals("")) {
ccAddrs = InternetAddress.parse(cc, false);
msg.setRecipients(Message.RecipientType.CC,
ccAddrs);
}
InternetAddress[] bccAddrs = null;
if ((bcc != null) && !bcc.equals("")) {
bccAddrs = InternetAddress.parse(bcc, false);
msg.setRecipients(Message.RecipientType.BCC,
toAddrs);
}
//subject
if((subject != null) && !subject.equals(""))
msg.setSubject(subject);
else
msg.setSubject("(no subject)");
//attachments
// create the Multipart and its parts to it
Multipart mp = new MimeMultipart();
MimeBodyPart mbp = new MimeBodyPart();
mbp.setText(body);
mp.addBodyPart(mbp);
// add the Multipart to the message
msg.setContent(mp);
Transport.send(msg);
return true;
}
catch(AddressException ex)
{
return false;
}
catch(MessagingException ex)
{
return false;
}
catch(Exception ex)
{
return false;
}
}
else
return false;
}
public boolean sendStatefulMessage(String to, String cc, String bcc,
String subject, String body)
{
try {
Message msg = new MimeMessage(this.session);
//to
InternetAddress[] toAddrs = null;
if ((to != null) && !to.equals("")) {
toAddrs = InternetAddress.parse(to, false);
msg.setRecipients(Message.RecipientType.TO,
toAddrs);
}
else
return false;
//sent date
msg.setSentDate(Calendar.getInstance().getTime());
//from
String fromAddress = url.getUsername() +
"@"+url.getHost();
msg.setFrom(new InternetAddress(fromAddress));
//cc
InternetAddress[] ccAddrs = null;
if ((cc != null) && !cc.equals("")) {
ccAddrs = InternetAddress.parse(cc, false);
msg.setRecipients(Message.RecipientType.CC,
ccAddrs);
}
InternetAddress[] bccAddrs = null;
if ((bcc != null) && !bcc.equals("")) {
bccAddrs = InternetAddress.parse(bcc, false);
msg.setRecipients(Message.RecipientType.BCC,
toAddrs);
}
//subject
if((subject != null) && !subject.equals(""))
msg.setSubject(subject);
else
msg.setSubject("(no subject)");
//attachments
// create the Multipart and its parts to it
Multipart mp = new MimeMultipart();
MimeBodyPart mbp = new MimeBodyPart();
mbp.setText(body);
mp.addBodyPart(mbp);
// add the Multipart to the message
msg.setContent(mp);
Transport.send(msg);
}
catch(AddressException ex)
{
return false;
}
catch(MessagingException ex)
{
return false;
}
catch(Exception ex)
{
return false;
}
return true;
}
/** Getter for property username.
* @return Value of property username.
*
*/
public String getUsername() {
return this.username;
}
/** Setter for property username.
* @param username New value of property username.
*
*/
public void setUsername(String username) {
this.username = username;
}
/** Getter for property password.
* @return Value of property password.
*
*/
public String getPassword() {
return this.password;
}
/** Setter for property password.
* @param password New value of property password.
*
*/
public void setPassword(String password) {
this.password = password;
}
/** Getter for property hostname.
* @return Value of property hostname.
*
*/
public String getHostname() {
return this.hostname;
}
/** Setter for property hostname.
* @param hostname New value of property hostname.
*
*/
public void setHostname(String hostname) {
this.hostname = hostname;
}
/** Getter for property protocol.
* @return Value of property protocol.
*
*/
public String getProtocol() {
return this.protocol;
}
/** Setter for property protocol.
* @param protocol New value of property protocol.
*
*/
public void setProtocol(String protocol) {
this.protocol = protocol;
}
}
#####################################################################
2. Create your deployment file for stateful service.
First you need a deployment file for your service that allows for a
stateful session handler. I am using the Session handler that comes with
axis. I place this file in the application context such as
<web-app>/wsdd/noimailservice-deploy.wsdd, so it is expected to be there
when the deployment servlet init is invoked.
<?xml version="1.0" encoding="UTF-8"?>
<!-- noimailservice-deploy.wsdd -->
<deployment
xmlns="http://xml.apache.org/axis/wsdd/"
xmlns:java="http://xml.apache.org/axis/wsdd/providers/java"
xmlns:xsd="http://www.w3.org/2000/10/XMLSchema"
xmlns:xsi="http://www.w3.org/2000/10/XMLSchema-instance">
<service name="NOIMailService" provider="java:RPC">
<namespace>http://meis/mailservlet/</namespace>
<parameter name="scope" value="session"/>
<requestFlow>
<handler
type="java:org.apache.axis.handlers.SimpleSessionHandler"/>
</requestFlow>
<responseFlow>
<handler
type="java:org.apache.axis.handlers.SimpleSessionHandler"/>
</responseFlow>
<parameter name="className"
value="com.noi.mailservlet.web.services.NOIMailService"/>
<parameter name="allowedMethods" value="*"/>
</service>
</deployment>
#####################################################################
3. Deploy the stateful service.
I use a servlet as part of the web application that will deploy the
service. When its init method is called it configures the server service
engine with the above wsdd. This will atomatically deploy the service
wen the web application file is deployed.
/*
* ServicesDeploymentServlet.java
*
* Created on April 1, 2003, 5:39 PM
*/
package com.noi.mailservlet.web.servlet;
import java.io.*;
import java.net.*;
import javax.servlet.*;
import javax.servlet.http.*;
import org.apache.axis.transport.http.*;
import org.apache.axis.*;
import org.apache.axis.deployment.wsdd.*;
import javax.xml.parsers.*;
import org.w3c.dom.*;
import org.xml.sax.*;
import com.noi.utility.data.*;
/**
*
* @author clay
* @version
*/
public class ServicesDeploymentServlet extends HttpServlet {
/** Initializes the servlet.
*/
public void init(ServletConfig sconfig) throws ServletException {
super.init(sconfig);
AxisServlet axisServlet = new AxisServlet();
ServletConfig sC = getServletConfig();
ServletContext context = this.getServletContext();
try {
axisServlet.init(sC);
} catch (ServletException e) {
e.printStackTrace();
}
try {
AxisEngine engine = axisServlet.getEngine();
String[] services = {"myservice", "noimailservice"};
for(int i=0; i<services.length; i++)
{
URL deployURL =
context.getResource("/wsdd/"+services[i]+"-deploy.wsdd");
XMLDocumentReader reader = new XMLDocumentReader();
reader.parse(deployURL);
Document doc = reader.getDocument();
Element element = doc.getDocumentElement();
WSDDDocument wsddDoc = new WSDDDocument(element);
EngineConfiguration config =
(EngineConfiguration)engine.getConfig();
if ( config instanceof WSDDEngineConfiguration) {
WSDDDeployment deployment =
((WSDDEngineConfiguration)config).getDeployment();
wsddDoc.deploy(deployment);
}
engine.refreshGlobalOptions();
engine.saveConfiguration();
}
}
catch (IOException e) {
e.printStackTrace();
}
}
/** Destroys the servlet.
*/
public void destroy() {
//this should undeploy
}
/** Processes requests for both HTTP <code>GET</code> and
<code>POST</code> methods.
* @param request servlet request
* @param response servlet response
*/
protected void processRequest(HttpServletRequest request,
HttpServletResponse response)
throws ServletException, IOException {
response.setContentType("text/html");
PrintWriter out = response.getWriter();
out.close();
}
/** Handles the HTTP <code>GET</code> method.
* @param request servlet request
* @param response servlet response
*/
protected void doGet(HttpServletRequest request, HttpServletResponse
response)
throws ServletException, IOException {
processRequest(request, response);
}
/** Handles the HTTP <code>POST</code> method.
* @param request servlet request
* @param response servlet response
*/
protected void doPost(HttpServletRequest request,
HttpServletResponse response)
throws ServletException, IOException {
processRequest(request, response);
}
/** Returns a short description of the servlet.
*/
public String getServletInfo() {
return "The Service Deployment Servlet";
}
}
#####################################################################
4. Create the client configuration file
I place this file in the application context such as
<web-app>/wsdd/noimailclient-deploy.wsdd, so it is expected to be there
when the client is invoked.
<?xml version="1.0" encoding="UTF-8"?>
<!-- noimailclient-deploy.wsdd -->
<deployment
xmlns="http://xml.apache.org/axis/wsdd/"
xmlns:java="http://xml.apache.org/axis/wsdd/providers/java"
xmlns:xsd="http://www.w3.org/2000/10/XMLSchema"
xmlns:xsi="http://www.w3.org/2000/10/XMLSchema-instance">
<transport name="http"
pivot="java:org.apache.axis.transport.http.HTTPSender"/>
<transport name="local"
pivot="java:org.apache.axis.transport.local.LocalSender"/>
<transport name="java"
pivot="java:org.apache.axis.transport.java.JavaSender"/>
<globalConfiguration>
<requestFlow>
<handler
type="java:org.apache.axis.handlers.SimpleSessionHandler"/>
</requestFlow>
<responseFlow>
<handler
type="java:org.apache.axis.handlers.SimpleSessionHandler"/>
</responseFlow>
</globalConfiguration>
</deployment>
#####################################################################
5. Use your client application
This particular application example provides both the stateful and
stateless versions.
package com.noi.mailservlet.test;
import org.apache.axis.client.*;
import org.apache.axis.*;
import org.apache.axis.encoding.XMLType;
import org.apache.axis.utils.Options;
import org.apache.axis.transport.http.*;
import org.apache.axis.deployment.wsdd.*;
import javax.xml.parsers.*;
import org.w3c.dom.*;
import org.xml.sax.*;
import java.net.*;
import javax.xml.namespace.QName;
import javax.xml.rpc.ParameterMode;
import javax.xml.rpc.ParameterMode;
import com.noi.utility.data.*;
public class NOIMailServiceClient
{
private static final boolean stateful = true;
public static void main(String [] args)
{
if(stateful)
sendStatelfulClient();
else
sendStatelessClient();
}
private static void sendStatelfulClient()
{
try {
String endpointURL =
"http://meis:8080/mailservlet/services/NOIMailService";
Service service = new Service();
//configure the stateful client engine
AxisEngine engine = service.getEngine().getClientEngine();
//get the configuration document
URL deployURL = new
URL("http://meis:8080/mailservlet/wsdd/noimailclient-deploy.wsdd");
XMLDocumentReader reader = new XMLDocumentReader();
reader.parse(deployURL);
Document doc = reader.getDocument();
Element element = doc.getDocumentElement();
//use the document to cofigure the client engine
WSDDDocument wsddDoc = new WSDDDocument(element);
EngineConfiguration config =
(EngineConfiguration)engine.getConfig();
if ( config instanceof WSDDEngineConfiguration) {
WSDDDeployment deployment =
((WSDDEngineConfiguration)config).getDeployment();
wsddDoc.deploy(deployment);
}
engine.refreshGlobalOptions();
engine.saveConfiguration();
//login
String protocol = "imap";
String username = "cgraham";
String password = "password";
String hostname = "newobjectivity.com";
Call call = (Call) service.createCall();
call.setTargetEndpointAddress( new java.net.URL(endpointURL)
);
//public boolean login(String protocol, String username,
String password, String hostname)
call.setOperationName( new QName("NOIMailService", "login")
);
call.addParameter( "protocol", XMLType.XSD_STRING,
ParameterMode.IN);
call.addParameter( "username", XMLType.XSD_STRING,
ParameterMode.IN);
call.addParameter( "password", XMLType.XSD_STRING,
ParameterMode.IN);
call.addParameter( "hostname", XMLType.XSD_STRING,
ParameterMode.IN);
call.setReturnType(
org.apache.axis.encoding.XMLType.XSD_BOOLEAN);
Boolean ret = (Boolean) call.invoke( new Object[] {
protocol, username, password, hostname } );
if(ret.booleanValue())
System.out.println(username+" has successfully logged
in.");
else
System.out.println(username+" login failure.");
//send message (stateful version)
String to = "[EMAIL PROTECTED]";
String cc = "[EMAIL PROTECTED]";
String bcc = "[EMAIL PROTECTED]";
String subject = "[NOI Mail Services] Service Test";
String body = "This is a test of NOI Mail Services";
call = (Call) service.createCall();
call.setTargetEndpointAddress( new java.net.URL(endpointURL)
);
//public boolean login(String protocol, String username,
String password, String hostname)
call.setOperationName( new QName("NOIMailService",
"sendStatefulMessage") );
call.addParameter( "to", XMLType.XSD_STRING,
ParameterMode.IN);
call.addParameter( "cc", XMLType.XSD_STRING,
ParameterMode.IN);
call.addParameter( "bcc", XMLType.XSD_STRING,
ParameterMode.IN);
call.addParameter( "subject", XMLType.XSD_STRING,
ParameterMode.IN);
call.addParameter( "body", XMLType.XSD_STRING,
ParameterMode.IN);
call.setReturnType(
org.apache.axis.encoding.XMLType.XSD_BOOLEAN);
ret = (Boolean) call.invoke( new Object[] { to, cc, bcc,
subject, body } );
if(ret.booleanValue())
System.out.println(username+" has successfully sent the
message:"+subject);
else
System.out.println(username+" send failure.");
} catch (Exception e) {
System.err.println(e.toString());
e.printStackTrace();
}
}
private static void sendStatelessClient()
{
try {
String endpointURL =
"http://meis:8080/mailservlet/services/NOIMailService";
Service service = new Service();
Call call = (Call) service.createCall();
call.setTargetEndpointAddress( new java.net.URL(endpointURL)
);
//login
String protocol = "imap";
String username = "cgraham";
String password = "password";
String hostname = "newobjectivity.com";
String to = "[EMAIL PROTECTED]";
String cc = "[EMAIL PROTECTED]";
String bcc = "[EMAIL PROTECTED]";
String subject = "[NOI Mail Services] Service Test";
String body = "This is a test of NOI Mail Services";
//public boolean sendMessage(String protocol, String
username, String password, String hostname, String to, String cc, String
bcc, String subject, String body)
call.setOperationName( new QName("NOIMailService",
"sendStatelessMessage") );
call.addParameter( "protocol", XMLType.XSD_STRING,
ParameterMode.IN);
call.addParameter( "username", XMLType.XSD_STRING,
ParameterMode.IN);
call.addParameter( "password", XMLType.XSD_STRING,
ParameterMode.IN);
call.addParameter( "hostname", XMLType.XSD_STRING,
ParameterMode.IN);
call.addParameter( "to", XMLType.XSD_STRING,
ParameterMode.IN);
call.addParameter( "cc", XMLType.XSD_STRING,
ParameterMode.IN);
call.addParameter( "bcc", XMLType.XSD_STRING,
ParameterMode.IN);
call.addParameter( "subject", XMLType.XSD_STRING,
ParameterMode.IN);
call.addParameter( "body", XMLType.XSD_STRING,
ParameterMode.IN);
call.setReturnType(
org.apache.axis.encoding.XMLType.XSD_BOOLEAN);
Boolean ret = (Boolean) call.invoke( new Object[] {
protocol, username, password, hostname, to, cc, bcc, subject, body } );
if(ret.booleanValue())
System.out.println(username+" has successfully sent the
message:"+subject);
else
System.out.println(username+" send failure.");
} catch (Exception e) {
System.err.println(e.toString());
e.printStackTrace();
}
}
}
###############################################################
That's it, in it's entirety. This cookbook should be published by
somebody in the user docs, or wherever people can find it without
extensive work because its basic stuff people need, and isn't obvious.
-----------------------------------------
Clay Graham
President
newObjectivity, Inc.
making the mobile-world-office
http://www.newobjectivity.com/
-----Original Message-----
From: Clay Graham [mailto:[EMAIL PROTECTED]
Sent: Thursday, April 03, 2003 10:25 AM
To: [EMAIL PROTECTED]
Subject: Stateful web services.
Hello Axis Users,
I am having a hard time finding out how to create a stateful web
service. For example, if you wanted a mail service you would want to be
able to login to a mail session, hold that session in state, and then
perform multiple actions on that session, like send message, get
messages, etc.
If this does not exist you would have to create a new mail session for
every action, which isn't very efficient, and means that parameter lists
become very large.
It would seem to me there would be something simillar to the JSESSIONID,
common in web applications, that would let the service client access a
stateful service.
Can anyone point point me at relevant documents and/or tutorials on how
to do this?
Thanks!
-----------------------------------------
Clay Graham
President
newObjectivity, Inc.
making the mobile-world-office
http://www.newobjectivity.com/