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
*/
publicclass SSOWebservice
{
/**
登陆并得到用户信息
*/
publicboolean 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都比较适用。