Absolutely. I am not real familiar with the development process of axis, but I am more than willing to try!
What I will try to do is make a nice package based on the existing docs, and then submit it (where?). ----------------------------------------- Clay Graham President newObjectivity, Inc. making the mobile-world-office http://www.newobjectivity.com/ -----Original Message----- From: Tom Jordahl [mailto:[EMAIL PROTECTED] Sent: Thursday, April 03, 2003 1:50 PM To: '[EMAIL PROTECTED]' Subject: RE: Stateful web services. Clay, This is great. Do you think you could check out the current Axis HTML docs and see if you can put together a patch that would integrate this in to it? Your code could just be new files in the samples directory. If you could do that, then put the info in a Bugzilla report, that would increase the chances that someone (me) would check it in to the tree for others. -- Tom Jordahl Macromedia Server Development -----Original Message----- From: Clay Graham [mailto:[EMAIL PROTECTED] Sent: Thursday, April 03, 2003 3:22 PM To: [EMAIL PROTECTED] Subject: RE: Stateful web services. [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/