|            
1、服务端
  这次要发布的web service非常简单。它的功能是把从客户端传入的字符串中的小写字母转变成大写字母,再返回给客户端。
  Soap 服务器采用apache的AXIS(可以从http://ws.apache.org/axis/下载),应用服务器可以选用各种servlet 容器,我这里采用的是weblogic。
  1.1 实现类的源代码:
 
  // StringProcessor.java package com.jagie.j2me.ws;
  public class StringProcessor {   public StringProcessor()   {   }
    public String process(String name)   {     return name.toUpperCase();   }
  }
  1.2 发布步骤 
  1.准备一个目录作为web application的发布目录,我这里的这个目录叫jagiews,这个目录的全路径中最好不要有空格和中文。我的发布目录结构如下: 
  2.编译StringProcessor.java,把生成的StringProcessor.class置于: \jagiews\WEB-INF\classes\com\jagie\j2me\ws目录下。 
  3.在jagiews\WEB-INF\lib 文件夹中置入以下axis服务器需要的jar文件 axis.jar,axis-ant.jar,commons-discovery.jar,commons-logging.jar,jaxrpc.jar,log4j-1.2.8.jar,saaj.jar ,wsdl4j.jar。这些文件可以在http://ws.apache.org/axis/下载。 
  4.在jagiews\WEB-INF目录下增加2个发布描述文件:  server-config.wsdd,web.xml。 #server-config.wsdd   <?xml version="1.0" encoding="UTF-8"?> <deployment xmlns= "http://xml.apache.org/axis/wsdd/"  xmlns:java= "http://xml.apache.org/axis/wsdd/providers/java">  <globalConfiguration>   <parameter name=   "adminPassword" value="admin"/>   <parameter name=   "attachments.Directory"    value="C:\Program Files   \Apache Tomcat 4.0\webapps   \axis\WEB-INF\attachments"/>   <parameter name=   "attachments.implementation"    value="org.apache.axis.   attachments.AttachmentsImpl"/>   <parameter name=   "sendXsiTypes"   value="true"/>   <parameter name=   "sendMultiRefs"    value="true"/>   <parameter name=   "sendXMLDeclaration"   value="true"/>   <parameter name=   "axis.sendMinimizedElements"    value="true"/>   <requestFlow>    <handler type=    "java:org.apache.axis.handlers.JWSHandler">     <parameter   name="scope"   value="session"/>    </handler>    <handler type=    "java:org.apache.axis.handlers.JWSHandler">     <parameter   name="scope"   value="request"/>     <parameter   name="extension"  value=".jwr"/>    </handler>   </requestFlow>  </globalConfiguration>  <handler name=  "LocalResponder"   type="java:org.apache.axis.  transport.local.LocalResponder"/>  <handler name="URLMapper"   type="java:org.apache.axis.  handlers.http.URLMapper"/>  <handler name="RPCDispatcher"   type="java:org.apache.axis.  providers.java.RPCProvider"/>  <handler name="Authenticate"   type="java:org.apache.axis.  handlers.SimpleAuthenticationHandler"/>  <handler name="MsgDispatcher"   type="java:org.apache.axis.  providers.java.MsgProvider"/>
   <service name="AdminService"  provider="java:MSG">   <parameter name="allowedMethods"   value="AdminService"/>   <parameter name="enableRemoteAdmin"    value="false"/>   <parameter name="className"    value="org.apache.axis.utils.Admin"/>   <namespace>   http://xml.apache.org/axis/wsdd/   </namespace>  </service>  <service name="Version"   provider="java:RPC">   <parameter name="allowedMethods"    value="getVersion"/>   <parameter name="className"   value="org.apache.axis.Version"/>  </service>  <!--  your service  begin-->   <service name="StringProcess"   provider="java:RPC">   <parameter name="allowedMethods"   value="process"/>   <parameter name="className"    value="com.jagie.j2me.   ws.StringProcessor"/>  </service> <!-- your service  end -->  <transport name="http">   <requestFlow>    <handler type="URLMapper"/>    <handler type=    "java:org.apache.axis.handlers.    http.HTTPAuthHandler"/>   </requestFlow>  </transport>  <transport name="local">   <responseFlow>    <handler type="java:org.apache.axis.    transport.local.LocalResponder"/>   </responseFlow>  </transport> </deployment>
  # web.xml
  <?xml version="1.0"  encoding="ISO-8859-1"?>
  <!DOCTYPE web-app     PUBLIC "-//Sun Microsystems,   Inc.//DTD Web Application 2.3//EN"     "http://java.sun.com  /j2ee/dtds/web-app_2.2.dtd">
  <web-app>   <display-name>Apache-Axis</display-name>   <servlet>     <servlet-name>AxisServlet</servlet-name>     <display-name>Apache-Axis   Servlet</display-name>     <servlet-class>         org.apache.axis.transport.http.AxisServlet     </servlet-class>   </servlet>
    <servlet>     <servlet-name>AdminServlet</servlet-name>     <display-name>Axis Admin Servlet</display-name>     <servlet-class>         org.apache.axis.transport.http.AdminServlet     </servlet-class>     <load-on-startup>100</load-on-startup>   </servlet>
    <servlet>     <servlet-name>SOAPMonitorService</servlet-name>     <display-name>SOAPMonitorService</display-name>     <servlet-class>         org.apache.axis.monitor.SOAPMonitorService     </servlet-class>     <init-param>       <param-name>SOAPMonitorPort</param-name>       <param-value>5001</param-value>     </init-param>     <load-on-startup>100</load-on-startup>   </servlet>
    <servlet-mapping>     <servlet-name>AxisServlet</servlet-name>     <url-pattern>/servlet/AxisServlet</url-pattern>   </servlet-mapping>
    <servlet-mapping>     <servlet-name>AxisServlet</servlet-name>     <url-pattern>*.jws</url-pattern>   </servlet-mapping>
    <servlet-mapping>     <servlet-name>AxisServlet</servlet-name>     <url-pattern>/services/*</url-pattern>   </servlet-mapping>
    <servlet-mapping>     <servlet-name>SOAPMonitorService</servlet-name>     <url-pattern>/SOAPMonitor</url-pattern>   </servlet-mapping>
   <!-- uncomment this if you want the admin servlet -->  <!--   <servlet-mapping>     <servlet-name>AdminServlet</servlet-name>     <url-pattern>/servlet/AdminServlet  </url-pattern>   </servlet-mapping>  -->
      <!-- currently the W3C havent settled   on a media type for WSDL;     http://www.w3.org/TR/2003/  WD-wsdl12-20030303/#ietf-draft     for now we go with the basic   ''it''s XML'' response -->   <mime-mapping>     <extension>wsdl</extension>      <mime-type>text/xml</mime-type>   </mime-mapping>   <mime-mapping>     <extension>xsd</extension>     <mime-type>text/xml</mime-type>   </mime-mapping> </web-app>  
   
  5.开启你的application server,把目录jagiews发布为一个名叫jagiews的web application。 
  6.测试:打开浏览器,输入网址(这里使用的是weblogic,其他的服务器请酌情修改): http://localhost:7001/jagiews/services/StringProcess?method=process&name=qqqq,如果浏览器能在返回的xml文档中显示字符串"QQQQ",恭喜你,你的web service发布成功了。如果发布不成功,请按以上发布步骤检查一下。 
  2、客户端 
  客户端自然是用MIDlet了,不过用什么方式来访问web service呢?其实有3种访问方式 
  直接用HttpConnection访问 http://localhost:7001/jagiews/services/StringProcess?method=process&name=qqqq,得到xml的返回数据,然后用kxml(http://kxml.enhydra.org/)解析,得到返回值。 
  如果你的手机支持MIDP2.0的话,可以考虑使用JSR172。 
  用ksoap api。 
  这里讲述第三种方式。使用之前,你需要从 http://ksoap.enhydra.org/software/downloads/index.html下载稳定的ksoap包,置于你的classpath中。 
  2.1 客户端源代码 
  2.1.1 WSClientMIDlet.java 
 
  package com.jagie.j2me.ws;
  import javax.microedition.midlet.*; import javax.microedition.lcdui.*;
  /**  * <p>Title: </p>  * <p>Description: </p>  * <p>Copyright: Copyright (c)  2004</p>  * <p>Company: </p>  * @author not attributable  * @version 1.0  */
  public class WSClientMIDlet     extends MIDlet  {   static WSClientMIDlet instance;
    public WSClientMIDlet()   {     instance = this;   }
    public void startApp()   {     Display display=  Display.getDisplay(this);     DisplayForm displayable =  new DisplayForm();     display.setCurrent(displayable);
    }
    public void pauseApp()   {   }
    public void destroyApp   (boolean unconditional)   {   }
    public static void quitApp()   {     instance.destroyApp(true);     instance.notifyDestroyed();     instance = null;   }
  }  
   
  2.1.2 DisplayForm.java 
 
  package com.jagie.j2me.ws; import javax.microedition.lcdui.*; /**  * <p>Title: </p>  * <p>Description: </p>  * <p>Copyright: Copyright (c)   2004</p>  * <p>Company: </p>  * @author not attributable  * @version 1.0  */
  public class DisplayForm     extends Form     implements CommandListener,   Runnable  {   private TextField textField1;   private Thread t;
    public DisplayForm()   {     super("字符转换webservice测试");
      try   {       jbInit();     }     catch (Exception e)  {       e.printStackTrace();     }
 
    }
    private void jbInit()   throws Exception    {     // Set up this Displayable   to listen to command events     textField1 = new TextField  ("", "", 15, TextField.ANY);     this.setCommandListener(this);     textField1.setLabel  ("待处理的字符串是:");     textField1.setConstraints  (TextField.ANY);     textField1.setInitialInputMode  ("Tester");     setCommandListener(this);     // add the Exit command     addCommand(new Command  ("Exit", Command.EXIT, 1));     addCommand(new Command  ("Process", Command.OK, 1));     this.append(textField1);   }
    public void commandAction   (Command command,   Displayable displayable)   {
      if (command.getCommandType  () == Command.EXIT)  {       WSClientMIDlet.quitApp();     }     else if (command.getCommandType()   == Command.OK)  {       t = new Thread(this);       t.start();     }   }
    public void run()   {     String s1 =  textField1.getString();     String s2 =  new StringProcessorStub().process(s1);     StringItem resultItem =  new StringItem("处理后的字符串是:", s2);     this.append(resultItem); } }  
   
  2.1.3 StringProcessorStub.java 
 
  package com.jagie.j2me.ws;
  import org.ksoap.*; import org.ksoap.transport.HttpTransport;
  /**  * <p>Title: </p>  * <p>Description: </p>  * <p>Copyright: Copyright (c) 2004</p>  * <p>Company: </p>  * @author not attributable  * @version 1.0  */
    public class StringProcessorStub   {     public StringProcessorStub()  {   }
    public String process(String name)   {     String result = null;     try  {
        SoapObject rpc =    new SoapObject     ("http://localhost:  7001/jagiews/services/StringProcess",   "process");
        rpc.addProperty("name", name);
        HttpTransport ht =    new HttpTransport     ("http://localhost:7001/  jagiews/services/StringProcess",  "");
        result = (String) ht.call(rpc);
      }     catch (Exception e) {       e.printStackTrace();     }
      return result;
    } }  
  总结 
  有了ksoap,手机上调用web service就很容易了。不过要注意的是,使用网络连接这种费时操作的时候,一定要单独开线程进行,不要直接写在commandAction()方法里,否则出现画面被锁住的情况。  
 |