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()方法裡,否則出現畫面被鎖住的情況。