Axis篇
Axis简介
Axis是Apache组织推出的SOAP引擎,Axis项目是Apache组织著名的SOAP项目的后继项目,目前最新版本是采用Java开发的1.1版本,C++的版本正在开发之中。Axis v1.1软件包可以从http://ws.apache.org/axis/dist/1_1/下载得到。
但是Axis不仅仅是一个SOAP引擎,它还包括:
1)、 一个独立运行的SOAP服务器
2)、一个servlet引擎的插件,这个servlet引擎可以是Tomcat
3)、对WSDL的扩展支持
4)、一个将WSDL的描述生成JAVA类的工具
5)、一些示例代码
6)、还有一个监控TCP/IP包的工具
図 2
SOAP简介
SOAP是一个基于XML的用于应用程序之间通信数据编码的传输协议。最初由微软和Userland Software提出,随着不断地完善和改进,SOAP很快被业界广泛应用,目前完全发布版本是1.1。在其发展过程中,W3C XML标准工作小组积极促成SOAP成为一个真正的开放标准。在写作此文档之时,SOAP1.2草案已经发布,1.2对1.1中相对混乱的部分做了改进。SOAP被广泛作为新一代跨平台、跨语言分布计算Web Services的重要部分。
Axis使用
提供服务实现类
//包名
package zpf; /** * 服务实现类的实现 * @author caoxiang */ public class SSOWebservice { /** 登陆并得到用户信息 */ public boolean login(String loginid, String password) { //判断用户是否登陆成功的标记 boolean ret = false; if (loginid.equals("caoxiang") && password.equals("caoxiang ")) ret = true; else ret = false; //返回 return ret; } }
配置web.xml
<?xml version="1.0" encoding="UTF-8"?> <web-app xmlns="http://java.sun.com/xml/ns/j2ee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" version="2.4" xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd"> <servlet> <servlet-name>XFireServlet</servlet-name> <servlet-class> org.codehaus.xfire.transport.http.XFireConfigurableServlet </servlet-class> <load-on-startup>0</load-on-startup> </servlet> <servlet-mapping> <servlet-name>XFireServlet</servlet-name> <url-pattern>/services/*</url-pattern> </servlet-mapping> <servlet> <servlet-name>AxisServlet</servlet-name> <servlet-class> org.apache.axis.transport.http.AxisServlet </servlet-class> </servlet> <servlet> <servlet-name>AdminServlet</servlet-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> <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> <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>
配置server-config.wsdd
<?xml version="1.0" encoding="gb2312"?> <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="enableNamespacePrefixOptimization" value="true" /> <parameter name="attachments.Directory" value="D:\jakarta-tomcat-5.0.28\webapps\axis\WEB-INF\attachments" /> <parameter name="disablePrettyXML" value="true" /> <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" /> <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="Authenticate" type="java:org.apache.axis.handlers.SimpleAuthenticationHandler" /> <!-- 自定义服务开始 --> <!-- 单点登陆服务 add by Zhang.P.F --> <service name="SSOWebservice" provider="java:RPC"> <parameter name="allowedMethods" value="*" /> <parameter name="className" value="zpf.SSOWebservice" /> <operation name="login" returnType="ns:boolean"> <parameter name="loginid" type="ns:String" /> <parameter name="password" type="ns:String" /> </operation> </service> <!-- 自定义服务结束 --> <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> <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> <transport name="http"> <requestFlow> <handler type="URLMapper" /> <handler type="java:org.apache.axis.handlers.http.HTTPAuthHandler" /> </requestFlow> <parameter name="qs:list" value="org.apache.axis.transport.http.QSListHandler" /> <parameter name="qs:wsdl" value="org.apache.axis.transport.http.QSWSDLHandler" /> <parameter name="qs.list" value="org.apache.axis.transport.http.QSListHandler" /> <parameter name="qs.method" value="org.apache.axis.transport.http.QSMethodHandler" /> <parameter name="qs:method" value="org.apache.axis.transport.http.QSMethodHandler" /> <parameter name="qs.wsdl" value="org.apache.axis.transport.http.QSWSDLHandler" /> </transport> <transport name="local"> <responseFlow> <handler type="LocalResponder" /> </responseFlow> </transport> </deployment>
客户端访问代码
import org.apache.axis.client.Call; import org.apache.axis.client.Service; import org.apache.axis.encoding.XMLType; import javax.xml.rpc.ParameterMode; /** * 客户端登陆类的实现 * @author caoxiang */ public class CallC { /** * 测试主程序 * @param args * @throws Exception */ public static void main(String [] args) throws Exception { try{ //服务路径 String endpoint = "http://localhost:5200/axis_sample/services/SSOWebservice"; //用户名 String user= new String("1"); //密 码 String password=new String("2"); //服务对象 Service service = new Service(); //调用服务的对象 Call call = (Call) service.createCall(); //设置目标服务 call.setTargetEndpointAddress(new java.net.URL(endpoint)); //设置调用的方法 call.setOperationName("login"); //设置参数 call.addParameter("loginid", XMLType.XSD_STRING, ParameterMode.IN); //设置参数 call.addParameter("password", XMLType.XSD_STRING, ParameterMode.IN); call.setReturnType(XMLType.XSD_BOOLEAN); //用于判断用户是否登陆的成功的标记 Boolean bv = false; //判断服务对象是否为空 if(call!=null) { //调用服务端程序,并接收服务端的返回值 bv = (Boolean)call.invoke(new Object[] {user, password}); } //如果登陆成功 if(bv) { System.out.println("用户登陆成功了" ); } else { System.out.println("用户登陆失败了" ); } } //异常处理 catch(Exception e){ //显示错误 e.printStackTrace(); } } }
文件上传与下载
因为项目中可能会用到web service提供的文件下载与上传功能,下面就简单举例介绍Axis中是如何实现文件上传与下载的。
● 创建服务类
package zpf; import java.io.File; import java.io.FileOutputStream; import java.io.IOException; import java.io.InputStream; import javax.activation.DataHandler; import javax.activation.FileDataSource; import org.apache.log4j.Logger; public class FileService { static Logger logger = Logger.getLogger(FileService.class.getName()); public static String Repository = "C://uploads"; public String putFile(DataHandler dh, String name) { if (name == null) name = "test.tmp"; logger.debug("文件名为空,设置文件名"); try { File dir = new File(Repository); if (!dir.exists()) { dir.mkdir(); logger.debug("附件存放目录为空,创建 uploads 目录"); } InputStream input = dh.getInputStream(); FileOutputStream fos = new FileOutputStream(new File(dir, "aa.txt")); byte[] buffer = new byte[1024 * 4]; int n = 0; while ((n = input.read(buffer)) != -1) { fos.write(buffer, 0, n); } input.close(); fos.close(); } catch (IOException e) { e.printStackTrace(); } return name + "send OK"; } public DataHandler[] getFile(String name) throws IOException { // File dir=new File(Repository); // if(!dir.exists()) // dir.mkdir(); // File data=new File(dir,name); // if(data.exists()) // return new DataHandler(new FileDataSource(data)); // else // return null; // } DataHandler ret[] = new DataHandler[1]; java.io.File myFile = new java.io.File("C:\\00.txt"); if (myFile.isFile() && myFile.canRead()) { String fname = myFile.getAbsoluteFile().getCanonicalPath(); ret[0] = new DataHandler(new FileDataSource(fname)); } return ret; } }
● 部署描叙文件
<service name="FileService" provider="java:RPC"> <parameter name="className" value="zpf.FileService"/> <parameter name="allowedMethods" value="*"/> <operation name="getFile" returnQName="returnqname" returnType="ns1:DataHandler" xmlns:SchemaNS="http://www.w3.org/2001/XMlSchema"> <parameter name="name" type="SchemaNS:string"/> </operation> <operation name="putFile" returnQName="returnqname" returnType="ns1:DataHandler" xmlns:SchemaNS="http://www.w3.org/2001/XMlSchema"> <parameter name="dh" type="ns1:DataHandler"/> <parameter name="name" type="SchemaNS:string"/> </operation> </service>
服务端代码
package zpf; import java.io.BufferedReader; import java.io.File; import java.io.FileWriter; import java.io.InputStreamReader; import org.apache.axis.client.Call; import org.apache.axis.client.Service; import org.apache.axis.encoding.XMLType; import org.apache.axis.encoding.ser.JAFDataHandlerDeserializerFactory; import org.apache.axis.encoding.ser.JAFDataHandlerSerializerFactory; import javax.activation.DataHandler; import javax.activation.FileDataSource; import javax.xml.namespace.QName; import javax.xml.rpc.ParameterMode; public class CallFileService { private String fileName; public static void main(String[] args) { CallFileService.doPut("C:\\00.txt"); } //文件上传 public void PutFile(String fileName) { this.fileName = fileName; } public boolean doPut() { return doPut(fileName); } public static boolean doPut(String fileName) { String name = fileName; try { String endpoint = "http://localhost:5200/axis_sample/services/FileService"; Service service = new Service(); Call call = (Call) service.createCall(); DataHandler dh = new DataHandler(new FileDataSource(fileName)); call.setTargetEndpointAddress(new java.net.URL(endpoint)); call.setOperationName(new QName(endpoint, "putFile")); QName qnameattachment = new QName("FileService", "DataHandler"); call.registerTypeMapping(dh.getClass(), qnameattachment, JAFDataHandlerSerializerFactory.class, JAFDataHandlerDeserializerFactory.class); call.addParameter("s1", qnameattachment, ParameterMode.IN); call.addParameter("s2", XMLType.XSD_STRING, ParameterMode.IN); call.setReturnType(XMLType.XSD_STRING); String uploadedFN = (String) call.invoke(new Object[] { dh, name }); if (uploadedFN != null && uploadedFN.trim().length() > 0) { return true; } } catch (Exception e) { //logger.error("调用文件上传Web服务出错:" + e.getMessage()); return false; } return false; } //文件下载: public void GetFile(String fileName) { this.fileName = fileName; } public boolean doGet() { return doGet(fileName); } public static boolean doGet(String fileName) { InputStreamReader ins = null; BufferedReader br = null; FileWriter fw = null; try { String endpoint = "http://localhost:5200/axis_sample/services/FileService"; Service service = new Service(); Call call = (Call) service.createCall(); DataHandler dh = new DataHandler(new FileDataSource(fileName)); call.setTargetEndpointAddress(new java.net.URL(endpoint)); call.setOperationName(new QName(endpoint, "getFile")); QName qnameattachment = new QName("FileService", "DataHandler"); call.registerTypeMapping(dh.getClass(), qnameattachment, JAFDataHandlerSerializerFactory.class, JAFDataHandlerDeserializerFactory.class); call.addParameter("s1", qnameattachment, ParameterMode.IN); call.setReturnType(new QName("FileService", "DataHandler"), DataHandler.class); DataHandler ret = (DataHandler) call .invoke(new Object[] { fileName }); ins = new InputStreamReader(ret.getInputStream()); br = new BufferedReader(ins); File dir = new File("DownLoadFile"); if (!dir.exists()) { dir.mkdir(); // logger.debug("下载文件存放目录不存在,创建 【"+dir.getAbsolutePath()+" 】目录"); } File f = new File(dir, fileName + "_reply"); fw = new FileWriter(f); String tmp = br.readLine(); while (tmp != null) { fw.write(tmp + "\n"); tmp = br.readLine(); } } catch (Exception e) { // logger.error("调用文件下载Web服务出错:" + e.getMessage()); return false; } finally { try { br.close(); ins.close(); fw.close(); } catch (Exception ee) { } } return false; } /* public static void main(String[] args) { try { Service service = new Service(); Call call = (Call) service.createCall(); call.setTargetEndpointAddress( "http://localhost:5200/axis_sample/services/FileService" ); call.setOperationName( "getFile" ); QName qnameAttachment = new QName("TransFile","DataHandler"); call.registerTypeMapping(DataHandler.class, qnameAttachment, JAFDataHandlerSerializerFactory.class,JAFDataHandlerDeserializerFactory.class); call.addParameter("a", XMLType.XSD_STRING ,ParameterMode.IN); call.setReturnType(XMLType.SOAP_ARRAY); javax.activation.DataHandler[] ret = (javax.activation.DataHandler[])call.invoke(new Object[]{"lishu"}); for (int i = 0; i < ret.length; i++) { DataHandler recDH = ret[i]; System.out.println(recDH.getName()); java.io.File receivedFile = new java.io.File("D:\\"+recDH.getName());//文件生成 } } catch (Exception ex) { ex.printStackTrace(); } } */ }
Axis总结
Axis做为soap4j的下一代开源框架,它提供了支持java SOAP服务器的API,但是Axis在配置文件和部署服务上都是比较繁琐的,在服务器性能方面Axis的性能没有用XFire部署的服务性能要高,但是Axis在发布客户端代码时比XFire要方便,因为Axis可以不需要服务端生成的接口和类便可以调用服务端程序,但是XFire需要服务端的程序或者服务端生成的客户端程序。虽然Axis没有比较全面的文档,但是Axis的接口还是比较简单的,可以进行简单的一次开发,对于部署,Axis配置文件虽然繁琐,但是都是XML文件的形式表达的,所以对于修改Axis文件还是比较简单的,之所以Axis的用户比XFire的用户要多,可能是Axis都是面向XML进行部署的,而其他的web service开源软件都是面向类和接口去部署,这点是Axis的部署和其他不同点,对于服务的兼容性Axis的支持性远远比其他的开源框架要多,在性能方面虽然Axis不足于XFire,但是Axis的性能还是比较可靠的。在兼容性方面Axis可以很好的和其他的web开发语言融合,而XFire只能支持有jdk1.5的环境,对于这点Axis无需jdk1.5的要求,所以说在这点,Axis领先于XFire。对于任何一个开发者不管你是开发web service还是开发web project,Axis都比较适用。