`
wuhongyu
  • 浏览: 406936 次
  • 性别: Icon_minigender_1
  • 来自: 哈尔滨
社区版块
存档分类
最新评论

JAVA6开发WebService (四)——SAAJ调用WebService

阅读更多

    前面写了个JAX-WS的小例子,看到用JAVA6开发WebService确实很简单,也很方便,不过前面也说了,JAVA有三种WebService规范,JAX-WS是其中一种,现在来看看JAXM&SAAJ。

 

    最近在做一个接口平台的项目,接口嘛,当然得涉及到对WebService的接口了,我们计划做成一个通用的平台,通过配置文件进行配置后就可以动态对某一个接口进行调用,但像前面的例子那样,每次都要生成一堆客户端代码,这可受不了。如果调用的接口唯一,生成一次客户端代码当然没问题,但如果要调用的接口是动态的,这就不好办了。因此,我需要了解SOAP更多底层的细节,由我自己来组织SOAP中的内容而不是完全由代码生成器生成。

 

    仍使用前面例子中的服务器端:

接口:

package com.why.server;

import javax.jws.WebParam;
import javax.jws.WebService;
import javax.jws.soap.SOAPBinding;
import javax.xml.ws.soap.MTOM;

/**
 * 
 * @author why
 *
 */
@WebService(name="Hello")
@SOAPBinding(style = SOAPBinding.Style.RPC)
public interface Hello {
	public void printContext();
	public Customer selectCustomerByName(@WebParam(name = "c",header=true)Customer customer);
	public Customer selectMaxAgeCustomer(Customer c1, Customer c2);
}

实现类:

package com.why.server;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Set;
import javax.activation.DataHandler;
import javax.activation.FileDataSource;
import javax.annotation.Resource;
import javax.jws.WebService;
import javax.xml.ws.WebServiceContext;
import javax.xml.ws.handler.MessageContext;
import javax.xml.ws.soap.MTOM;

/**
 * 
 * 通过@MTOM注解启动MTOM传输方式,使用CXF实现时,这个注解放在接口或者实现类上都可以,使用JDK1.6自带实现时,需标注在实现类上
 * @author why
 *
 */
@WebService(serviceName="HelloService",portName="HelloServicePort",targetNamespace="http://service.why.com/",endpointInterface="com.why.server.Hello")
@MTOM
public class HelloImpl implements Hello {
	
	@Resource
	private WebServiceContext context;
	
	@Override
	public void printContext(){
		MessageContext ctx = context.getMessageContext();
		Set<String> set = ctx.keySet();
		for (String key : set) {
			System.out.println("{" + key + "," + ctx.get(key) +"}");
			try {
				System.out.println("key.scope=" + ctx.getScope(key));
			} catch (Exception e) {
				System.out.println(key + " is not exits");
			}
		}
	}
	
	@Override
	public Customer selectCustomerByName(Customer customer) {
		if("why".equals(customer.getName())){
			customer.setId(1);
			try {
				customer.setBirthday(new SimpleDateFormat("yyyy-MM-dd").parse("1985-10-07"));
			} catch (ParseException e) {
				e.printStackTrace();
			}
			customer.setImageData(new DataHandler(new FileDataSource(new File("c:"+ File.separator + "why.jpg"))));
		}else{
			customer.setId(2);
			customer.setBirthday(new Date());
			customer.setImageData(new DataHandler(new FileDataSource(new File("c:"+ File.separator + "origin.jpg"))));
		}
		return customer;
	}
	
	@Override
	public Customer selectMaxAgeCustomer(Customer c1, Customer c2) {
		try {
			// 输出接收到的附件
			System.out.println("c1.getImageData().getContentType()=" + c1.getImageData().getContentType());
			InputStream is = c1.getImageData().getInputStream();
			OutputStream os = new FileOutputStream("c:\\temp1.jpg");
			byte[] bytes = new byte[1024];
			int c;
			while ((c = is.read(bytes)) != -1) {
				os.write(bytes, 0, c);
			}
			os.close();
			
			System.out.println("c2.getImageData().getContentType()=" + c2.getImageData().getContentType());
			is = c2.getImageData().getInputStream();
			os = new FileOutputStream("c:\\temp2.jpg");
			bytes = new byte[1024];
			while ((c = is.read(bytes)) != -1) {
				os.write(bytes, 0, c);
			}
			os.close();
		} catch (IOException e) {
			e.printStackTrace();
		}
		
		if (c1.getBirthday().getTime() > c2.getBirthday().getTime()){
			return c2;
		}
		else{
			return c1;
		}
	}
}

Customer类:

package com.why.server;

import java.util.Date;

import javax.activation.DataHandler;
import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlMimeType;
import javax.xml.bind.annotation.XmlRootElement;

/**
 * 
 * @author why
 *
 */
@XmlRootElement(name = "Customer")
@XmlAccessorType(XmlAccessType.FIELD)
public class Customer {
	private long id;
	private String name;
	private Date birthday;
	@XmlMimeType("application/octet-stream")
	private DataHandler imageData;
	
	public long getId() {
		return id;
	}
	public void setId(long id) {
		this.id = id;
	}
	public String getName() {
		return name;
	}
	public void setName(String name) {
		this.name = name;
	}
	public Date getBirthday() {
		return birthday;
	}
	public void setBirthday(Date birthday) {
		this.birthday = birthday;
	}
	public DataHandler getImageData() {
		return imageData;
	}
	public void setImageData(DataHandler imageData) {
		this.imageData = imageData;
	}
}

发布:

package com.why.server;

import javax.xml.ws.Endpoint;

/**
 * 
 * @author why
 *
 */
public class SoapServer {
	public static void main(String[] args) {
		Endpoint.publish("http://localhost:8080/helloService",new HelloImpl());

	}
}

 

    这次不生成客户端类,而是通过自己组织SOAP消息,向服务器发送请求。首先,我们需要一个到WebService服务的连接(就像Connection之于JDBC),通过javax.xml.soap.SOAPConnectionFactory的createConnection()可以获得一个WebService连接。获得连接之后,我们就可以组织我们的SOAP消息了。通过javax.xml.soap.MessageFactory的createMessage()方法,获得一个javax.xml.soap.SOAPMessage,SOAPMessage就是我们SOAP消息的入口。我们知道,SOAP其实就是一个XML,有了SOAPMessage这个入口,剩下的就是对XML的组织和解析了。对于SOAP消息的各个部分,SOAPMessage都有对应的接口:

		// 获取SOAP连接工厂
		SOAPConnectionFactory factory = SOAPConnectionFactory.newInstance();
		// 从SOAP连接工厂创建SOAP连接对象
		SOAPConnection connection = factory.createConnection();
		// 获取消息工厂
		MessageFactory mFactory = MessageFactory.newInstance();
		// 从消息工厂创建SOAP消息对象
		SOAPMessage message = mFactory.createMessage();
		// 创建SOAPPart对象
		SOAPPart part = message.getSOAPPart();
		// 创建SOAP信封对象
		SOAPEnvelope envelope = part.getEnvelope();
		// 创建SOAPHeader对象
		SOAPHeader header = message.getSOAPHeader();
		// 创建SOAPBody对
		SOAPBody body = envelope.getBody();
 

    把我们需要传递的参数组织好,通过connection.call方法进行对WebService的调用,他仍然会给我们返回一个SOAPMessage对象,对应服务器端的三个函数,我分别写了对应的三个方法对其进行调用,以下是我的客户端类:

 

package com.why.client;
import java.io.ByteArrayOutputStream;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.URL;
import java.util.Iterator;
import java.util.UUID;
import javax.activation.DataHandler;
import javax.activation.FileDataSource;
import javax.xml.namespace.QName;
import javax.xml.soap.AttachmentPart;
import javax.xml.soap.MessageFactory;
import javax.xml.soap.SOAPBody;
import javax.xml.soap.SOAPBodyElement;
import javax.xml.soap.SOAPConnection;
import javax.xml.soap.SOAPConnectionFactory;
import javax.xml.soap.SOAPElement;
import javax.xml.soap.SOAPEnvelope;
import javax.xml.soap.SOAPHeader;
import javax.xml.soap.SOAPHeaderElement;
import javax.xml.soap.SOAPMessage;
import javax.xml.soap.SOAPPart;

/**
 * 
 * @author why
 *
 */
public class SoapClient {
	public static void main(String[] args) throws Exception{
		
		printContext();
		
		selectCustomerByName();
		
		selectMaxAgeCustomer();
	}
	
	/**
	 * 调用一个无参函数
	 * @throws Exception
	 */
	public static void printContext() throws Exception{
		// 获取SOAP连接工厂
		SOAPConnectionFactory factory = SOAPConnectionFactory.newInstance();
		// 从SOAP连接工厂创建SOAP连接对象
		SOAPConnection connection = factory.createConnection();
		// 获取消息工厂
		MessageFactory mFactory = MessageFactory.newInstance();
		// 从消息工厂创建SOAP消息对象
		SOAPMessage message = mFactory.createMessage();
		// 创建SOAPPart对象
		SOAPPart part = message.getSOAPPart();
		// 创建SOAP信封对象
		SOAPEnvelope envelope = part.getEnvelope();
		// 创建SOAPHeader对象
		SOAPHeader header = message.getSOAPHeader();
		// 创建SOAPBody对象
		SOAPBody body = envelope.getBody();
		
		// 创建XML的根元素
		SOAPBodyElement bodyElementRoot = body.addBodyElement(new QName("http://server.why.com/", "printContext", "ns1"));
		
		// 访问Web服务地址
		SOAPMessage reMessage = connection.call(message, new URL("http://127.0.0.1:8080/helloService"));
		// 控制台输出返回的SOAP消息
		OutputStream os = System.out;
		reMessage.writeTo(os);
		
		connection.close();
	}
	
	/**
	 * 调用一个在soap:HEADER中传递参数的函数
	 * @throws Exception
	 */
	public static void selectCustomerByName() throws Exception{
		// 获取SOAP连接工厂
		SOAPConnectionFactory factory = SOAPConnectionFactory.newInstance();
		// 从SOAP连接工厂创建SOAP连接对象
		SOAPConnection connection = factory.createConnection();
		// 获取消息工厂
		MessageFactory mFactory = MessageFactory.newInstance();
		// 从消息工厂创建SOAP消息对象
		SOAPMessage message = mFactory.createMessage();
		// 创建SOAPPart对象
		SOAPPart part = message.getSOAPPart();
		// 创建SOAP信封对象
		SOAPEnvelope envelope = part.getEnvelope();
		// 创建SOAPHeader对象
		SOAPHeader header = message.getSOAPHeader();
		// 创建SOAPBody对象
		SOAPBody body = envelope.getBody();
		
		// 创建XML的根元素
		SOAPHeaderElement headerElementRoot = header.addHeaderElement(new QName("http://server.why.com/", "c", "ns1"));
		SOAPBodyElement bodyElementRoot = body.addBodyElement(new QName("http://server.why.com/", "selectCustomerByName", "ns1"));
		headerElementRoot.addChildElement(new QName("name")).addTextNode("why");
		
		// 访问Web服务地址
		SOAPMessage reMessage = connection.call(message, new URL("http://127.0.0.1:8080/helloService"));
		// 控制台输出返回的SOAP消息
		OutputStream os = System.out;
		reMessage.writeTo(os);
		
		// 输出SOAP消息中的附件
		Iterator<AttachmentPart> it = reMessage.getAttachments();
		while (it.hasNext()) {
			InputStream ins = it.next().getDataHandler().getInputStream();
			byte[] b = new byte[ins.available()];
			OutputStream ous = new FileOutputStream("c:\\aaa.jpg");
			while (ins.read(b) != -1) {
				ous.write(b);
			}
			ous.close();
		}
		connection.close();
	}
	
	/**
	 * 调用一个在soap:Body中传递参数的函数
	 * @throws Exception
	 */
	public static void selectMaxAgeCustomer() throws Exception{
		// 获取SOAP连接工厂
		SOAPConnectionFactory factory = SOAPConnectionFactory.newInstance();
		// 从SOAP连接工厂创建SOAP连接对象
		SOAPConnection connection = factory.createConnection();
		// 获取消息工厂
		MessageFactory mFactory = MessageFactory.newInstance();
		// 从消息工厂创建SOAP消息对象
		SOAPMessage message = mFactory.createMessage();
		// 创建SOAPPart对象
		SOAPPart part = message.getSOAPPart();
		// 创建SOAP信封对象
		SOAPEnvelope envelope = part.getEnvelope();
		// 创建SOAPHeader对象
		SOAPHeader header = message.getSOAPHeader();
		// 创建SOAPBody对象
		SOAPBody body = envelope.getBody();

		// 设置Content-Type
		MimeHeaders hd = message.getMimeHeaders(); 
		hd.setHeader("Content-Type", "application/xop+xml; charset=utf-8; type=\"text/xml\"");

		// 创建XML的根元素
		SOAPBodyElement bodyElementRoot = body.addBodyElement(new QName("http://server.why.com/", "selectMaxAgeCustomer", "ns1"));
		
		// 创建Customer实例1
		SOAPElement elementC1 = bodyElementRoot.addChildElement(new QName("arg0"));
		elementC1.addChildElement(new QName("id")).addTextNode("1");
		elementC1.addChildElement(new QName("name")).addTextNode("A");
		elementC1.addChildElement(new QName("birthday")).addTextNode("1989-01-28T00:00:00.000+08:00");
		// 创建附件对象
		AttachmentPart attachment = message.createAttachmentPart(new DataHandler(new FileDataSource("c:\\c1.jpg")));
		// 设置Content-ID
		attachment.setContentId("<" + UUID.randomUUID().toString() + ">");
		attachment.setMimeHeader("Content-Transfer-Encoding", "binary");
		message.addAttachmentPart(attachment);
		SOAPElement elementData = elementC1.addChildElement(new QName("imageData"));
		
		// 添加XOP支持
		elementData.addChildElement(
				new QName("http://www.w3.org/2004/08/xop/include", "Include","xop"))
				.addAttribute(new QName("href"),"cid:" + attachment.getContentId().replaceAll("<", "").replaceAll(">", ""));
		
		// 创建Customer实例2
		SOAPElement elementC2 = bodyElementRoot.addChildElement(new QName("arg1"));
		elementC2.addChildElement(new QName("id")).addTextNode("2");
		elementC2.addChildElement(new QName("name")).addTextNode("B");
		elementC2.addChildElement(new QName("birthday")).addTextNode("1990-01-28T00:00:00.000+08:00");
		AttachmentPart attachment2 = message.createAttachmentPart(new DataHandler(new FileDataSource("c:\\c2.jpg")));
		attachment2.setContentId("<" + UUID.randomUUID().toString() + ">");
		message.addAttachmentPart(attachment2);
		SOAPElement elementData2 = elementC2.addChildElement(new QName("imageData"));
		
		elementData2.addChildElement(
				new QName("http://www.w3.org/2004/08/xop/include", "Include","xop"))
				.addAttribute(new QName("href"),"cid:" + attachment2.getContentId().replaceAll("<", "").replaceAll(">", ""));
		
		// 控制台输出发送的SOAP消息
		OutputStream os = new ByteArrayOutputStream();
		message.writeTo(os);
		String soapStr = os.toString();
		System.out.println("\n@@@@@@@@@@@@@@@@@@\n"+soapStr+"\n@@@@@@@@@@@@@@@@@@");
		
		// 访问Web服务地址
		SOAPMessage reMessage = connection.call(message, new URL("http://127.0.0.1:8080/helloService"));
		// 控制台输出返回的SOAP消息
		OutputStream baos = new ByteArrayOutputStream();
		reMessage.writeTo(baos);
		String soapStr2 = baos.toString();
		System.out.println("\n#############\n"+soapStr2+"\n################");
		
//		// 输出SOAP消息中的第一个子元素的元素名称
		System.out.println("\n<<<<<<<<<<<<<<<<<<<" + reMessage.getSOAPBody().getFirstChild().getLocalName());
		// 输出SOAP消息中的附件
		Iterator<AttachmentPart> it = reMessage.getAttachments();
		while (it.hasNext()) {
			InputStream ins = it.next().getDataHandler().getInputStream();
			byte[] b = new byte[ins.available()];
			OutputStream ous = new FileOutputStream("c:\\bbb.jpg");
			while (ins.read(b) != -1) {
				ous.write(b);
			}
			ous.close();
		}
		
		connection.close();
		
	}
}

 

    使用SAAJ创建附件时,需设置Content-Type=application/xop+xml; charset=utf-8; type="text/xml",否则服务器端获取不到这个附件,查看发送给服务器端的SOAP消息可以看到,默认Content-Type被置为text/xml; charset=utf-8,因此,需在代码中加入:

MimeHeaders hd = message.getMimeHeaders(); 
hd.setHeader("Content-Type", "application/xop+xml; charset=utf-8; type=\"text/xml\"");
 

    SOAPMessage有一个writeTo(OutputStream os)方法,可以将整个SOAP消息的内容写入一个输出流中,我们可以截获这个输出流的内容进行分析或再次整理。

 

附件是我的工程(2010-11-15更新)

 

4
0
分享到:
评论
4 楼 -小白 2014-08-20  
为什么 在
public Customer selectCustomerByName(Customer customer) {
if("why".equals(customer.getName())){

传过来的customer是空的,报错  是没有传过来吗

SOAPHeaderElement headerElementRoot = header.addHeaderElement(new QName("http://server.why.com/", "c", "ns1")); 
        SOAPBodyElement bodyElementRoot = body.addBodyElement(new QName("http://server.why.com/", "selectCustomerByName", "ns1")); 
        headerElementRoot.addChildElement(new QName("name")).addTextNode("why"); 

这里是设的一个customer对象吗?

谢谢!!
3 楼 guodage003 2013-12-30  
为什么我输出的有一大部分是乱码?
2 楼 wuhongyu 2010-12-03  
zfanxu 写道
我对着你的例子添加了一些方法:如果服务端写一个方法,参数是对象数组或是LIST<?>这样的形式,客户端用SAAJ生成SOAP消息时该做如何改动?
eg:服务端:public void xxx(Customer[] c);

或是我另写一个Customer的Javabean类:Customers{
   List<customer> custm;

...
}

服务端方法:public void xxx(Customers cs);

这个时候参数中的对象包含有List类型的参数,消息文件又该如何编写!?

望指教!~~~


对于数组形式,查看wsdl文件可以看到,会被封装成类似这种方式:
<xs:complexType name="customerArray" final="#all">
    <xs:sequence>
        <xs:element name="item" type="tns:customer" minOccurs="0" maxOccurs="unbounded" nillable="true"/>
    </xs:sequence>
</xs:complexType>
所以,在封装的时候,只要将其封装为
<arg0>
    <item>
        <Customer>...</Customer>
    </item>
    <item>
        <Customer>...</Customer>
    </item>
    ...
</arg0>
这样的层次结构就可以了。

对于集合,使用JDK自带的实现时,貌似不能直接传递,但可以变通一下:自定义一个bean,将要传递的list作为这个bean的属性就可以传递了,也就是说,对象内的list是可以传递的。
public class CustomerList{
    private ArrayList list;
    private HashMap map;
    //get and set method
}
SOAP封装List或Map时类似这样的方式:
<list>aaa</list>
<list>bbb</list>
<map>
    <entry>
        <key>1</key>
        <value>111</value>
    </entry>
    <entry>
        <key>2</key>
        <value>222</value>
    </entry>
</map>
不过我觉得应该尽量避免使用这种特定语言的内置对象。
若使用其他实现,如CXF,可以直接传递,SOAP消息中封装方式与数组类似,不知道是JDK的BUG还是人家压根没考虑实现这种方式。

如果说的不对,还望大侠们指教啊!


1 楼 zfanxu 2010-12-02  
我对着你的例子添加了一些方法:如果服务端写一个方法,参数是对象数组或是LIST<?>这样的形式,客户端用SAAJ生成SOAP消息时该做如何改动?
eg:服务端:public void xxx(Customer[] c);

或是我另写一个Customer的Javabean类:Customers{
   List<customer> custm;

...
}

服务端方法:public void xxx(Customers cs);

这个时候参数中的对象包含有List类型的参数,消息文件又该如何编写!?

望指教!~~~

相关推荐

    JAVA6开发WebService (二)——JAX-WS例子

    本篇文章将深入探讨如何使用JAX-WS(Java API for XML Web Services)在JAVA6环境中开发Web服务。JAX-WS是Java平台上的一个核心API,用于构建和消费Web服务,它简化了SOAP(Simple Object Access Protocol)消息处理...

    java 调用https webservice实例及axis包

    在Java开发中,调用HTTPS发布的Web Service接口是一项常见的任务,尤其在企业级应用中,HTTPS提供了安全的数据传输。本文将详细介绍如何使用Apache Axis库来实现这一功能,并提供相关步骤和注意事项。 首先,理解...

    JAVA的WebService支持CXF与SAAJ第三版

    ### JAVA的WebService支持CXF与SAAJ第三版——详细知识点概述 #### 一、引言 本教程旨在深入探讨如何使用CXF框架开发WebService,同时涵盖了多种与WebService相关的技术规范,包括但不限于JAX-WS、JAX-RS、JAX-RPC...

    webservice接口调用工具类依赖jar包

    WebService接口调用工具类...总之,调用WebService接口需要一系列的Java库支持,这些库提供了从解析WSDL到构建和发送SOAP请求,再到处理响应的所有功能。理解并正确使用这些jar包是成功调用WebService接口的关键步骤。

    java版WebService生成客户端和服务端的实例

    从准备必要的jar包,到编写服务接口和实现,再到生成和部署服务,以及创建客户端并调用服务,这一系列过程涵盖了WebService开发的关键步骤。理解并掌握这些知识,将有助于你在实际工作中灵活运用WebService进行跨...

    使用Http post的方式调用webservice

    本文将深入探讨如何在Java环境中,利用HTTP POST方法调用WebService,并解决可能遇到的问题。 首先,理解HTTP POST方法。POST是HTTP协议中的一个请求方法,用于向服务器发送数据。在调用WebService时,POST方法可以...

    java webservice 详细开发示例介绍

    ### Java WebService 详细开发示例介绍 #### 一、引言 随着互联网技术的发展,分布式系统的构建变得越来越重要。WebService作为一种实现系统间通信的重要手段,被广泛应用于各种场景之中。本文将详细介绍Java中...

    webservice在java中客户端调用

    7. **lib特别需要的包**:在提供的压缩包中,"lib特别需要的包"可能包含了Apache Axis或者其他相关库,这些库是Java客户端调用WebService所必需的,如axis.jar、wsdl4j.jar、saaj-api.jar等。确保将这些库添加到项目...

    java axis 调用C# webService所需的jar包

    在Java开发中,有时我们需要与使用不同技术栈的系统进行集成,例如调用C#编写的Web服务。在这种情况下,Axis作为一个成熟的SOAP客户端框架,可以帮助Java开发者实现对C# WebService的调用。本文将详细讲解如何使用...

    JAVA 的WebService 支持

    - **定义**:JAXM(Java API for XML Messaging)和SAAJ(SOAP with Attachments API for Java)是另一组基于SOAP的WebService规范。 - **API位置**:JAXM的API位于`javax.messaging.*`包下,SAAJ的API则位于`javax....

    java的webservice服务端程序

    - 在提供的压缩包中,可能包含了如`axis2`, `jaxws-api`, `saaj-api`, `wsdl4j`等jar包,它们是Java开发WebService所必需的库文件,用于处理SOAP消息、解析WSDL文件和执行其他相关任务。 4. **内部逻辑代码实现**...

    利用AXIS调用webservice所需JAR包

    本篇文章将深入探讨如何利用AXIS调用WebService,以及所需的JAR包及其作用。 首先,理解AXIS的基本概念至关重要。Apache Axis是Apache软件基金会开发的一个开源项目,它是一个用于构建Web服务和客户端的工具集。...

    java调用webservice axis 客户端 服务器端 包含jar包

    Java调用WebService是Web服务交互中的常见场景,而Axis作为Apache组织开发的一个开源工具,专门用于简化Java应用程序与Web服务的交互。本篇文章将详细解析如何使用Java通过Axis客户端调用WebService,以及如何搭建和...

    WebService结合java开发技术

    WebService结合Java开发技术,是利用Java强大的网络编程能力,以及WebService强大的分布式处理能力,实现应用程序之间跨平台、跨语言的通信。 SOA(面向服务的架构)是一种架构模式,其中服务是自包含的、模块化的...

    axis1.4带lib包java开发webservice客户端和服务端

    标题 "axis1.4带lib包java开发webservice客户端和服务端" 涉及到的是一个基于Java的Web服务开发工具包,Axis1.4,它包含必要的库文件(lib)来支持创建和消费Web服务。这个压缩包是为MyEclipse集成开发环境设计的,...

Global site tag (gtag.js) - Google Analytics