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都比较适用。