webservice在java中的应用-学习笔记(一):概念、发布、调用

 

目录

一、概念

二、一个简单的WebService使用

1、建立WebService的server

2、建立WebService的client

三、实际项目中WebService的发布和调用

1、发布WebService

a)发布方式一:不打jar包

b)发布方式二:打jar包的方式

2、调用WebService的服务

a)调用方式1:wsdl2java生成客户端代码方式调用

b)调用方式2:RPC远程调用

c)调用方式3:document方式调用


一、概念

WebService就是远程调用技术,也叫XML Web Service。WebService是一种可以接收从Internet或者Intranet上的其它系统中传递过来的请求,轻量级的独立的通讯技术。它是通过Soap在Web上提供的软件服务,使用Wsdl文件进行说明,并通过UDDI进行注册。

XML+XSD、Soap和Wsdl构成WebService平台的三大技术:

  1. XML:(Extensible Markup Language)扩展型可标记语言。WebService采用HTTP协议传输数据,采用XML格式封装数据(即XML中说明调用远程服务对象的哪个方法,传递的参数是什么,以及服务对象的返回结果是什么)。XML解决了数据表示的问题,但它没有定义一套标准的数据类型,更没有说怎么去扩展这套数据类型。例如,整形数到底代表什么?16位,32位,64位?这些细节对实现互操作性很重要。XML Schema(XSD)就是专门解决这个问题的一套标准。它定义了一套标准的数据类型,并给出了一种语言来扩展这套数据类型。WebService平台就是用XSD来作为其数据类型系统的。当你用某种语言(如VB.NET或C#)来构造一个Web service时,为了符合WebService标准,所有你使用的数据类型都必须被转换为XSD类型。你用的工具可能已经自动帮你完成了这个转换,但你很可能会根据你的需要修改一下转换过程。
  2. Soap:(Simple Object Access Protocol)简单对象存取协议。是XML Web Service的通信协议。当用户通过UDDI找到你的WSDL描述文档后,他可以通过SOAP调用你建立的Web服务中的一个或多个操作。Soap是XML文档形式的调用方法的规范,它可以支持不同的底层接口。WebService通过HTTP协议发送请求和接收结果时,发送的请求内容和结果内容都采用XML格式封装,并增加了一些特定的HTTP消息头,以说明HTTP消息的内容格式,这些特定的HTTP消息头和XML内容格式就是Soap协议。Soap提供了标准的RPC方法来调用Web Service。
  3. Wsdl:(Web Services Description Language)是一个XML文档,WebService务器端首先要通过一个Wsdl文件来说明自己家里有啥服务可以对外调用,服务是什么(服务中有哪些方法,方法接受的参数是什么,返回值是什么),服务的网络地址用哪个url地址表示,服务通过什么方式来调用。Wsdl文件保存在Web服务器上,通过一个url地址就可以访问到它。客户端要调用一个WebService服务之前,要知道该服务的Wsdl文件的地址。 WebService服务提供商可以通过两种方式来暴露它的Wsdl文件地址:1.注册到UDDI服务器,以便被人查找;2.直接告诉给客户端调用者。

二、一个简单的WebService使用

1、建立WebService的server

——编写服务方法的接口

public interface TestWebService {
	public String getServerReturn(String info);
}

——编写服务方法的实现类(加@WebService注解)

import javax.jws.WebService;
import lxw.webservice.server.TestWebService;

@WebService
public class TestWebServiceImpl implements TestWebService{
	@Override
	public String getServerReturn(String info) {
		return info+"********server return";
	}
}

——发布服务

import javax.xml.ws.Endpoint;
import lxw.webservice.server.impl.TestWebServiceImpl;

public class TestWebServicePublish {
	public static void main(String[] args) {
		Endpoint.publish("http://localhost:9999/getReturn", new TestWebServiceImpl());
		System.out.println("服务发布成功");
	}
}

——检查服务是否发布成功

访问http://localhost:9999/getReturn?wsdl是否能显示 

2、建立WebService的client

——使用wsimport命名自动生成客户端代码

——将生成的代码拷贝到client工程中

——编写客户端调用类调用对应服务

此处的TestWebServiceImpl是命令生成的接口,不是步骤一服务工程中编写的TestWebServiceImpl。QName中的值为wsdl中的targetNamespace和name属性的值。

import java.net.MalformedURLException;
import java.net.URL;
import javax.xml.namespace.QName;
import javax.xml.ws.Service;

public class TestWebServiceClient {

	public static void main(String[] args) throws MalformedURLException {
		Service service = Service.create(new URL("http://localhost:9999/getReturn?wsdl"), 
				new QName("http://impl.server.webservice.lxw/","TestWebServiceImplService"));
		TestWebServiceImpl impl = service.getPort(TestWebServiceImpl.class);
		System.out.println(impl.getServerReturn("test hello world"));
	}

}

三、实际项目中WebService的发布和调用

实际项目中,WebService的发布和调用一般使用Axis2或CXF框架,本文仅对Axis2框架的使用进行介绍。

1、发布WebService

a)发布方式一:不打jar包

——下载Axis2的相关jar包:http://axis.apache.org/axis2/java/core/download.html

——新建一个web工程,引入Axis2的jar包;

——在WEB-INF/services/自定义名称/META-INF路径下建立services.xml文件,用来描述WebServices;

——配置web.xml,增加AxisServlet的映射;

——编写相关的服务类,运行web工程;

——浏览器中访问相关链接,可以看到wsdl文件内容。

<!-- services.xml文件 -->
<?xml version="1.0" encoding="UTF-8"?>
<service name="MyTestWebServiceOne"><!-- 指定服务名 -->
    <description>
        MyTestWebServiceOne
    </description>
    <parameter name="ServiceClass"><!-- 服务类的位置 -->
        lxw.webservice.server.TestWebServiceOne
    </parameter>
    <messageReceivers>
    	<messageReceiver mep="http://www.w3.org/2004/08/wsdl/in-only"
           	class="org.apache.axis2.rpc.receivers.RPCInOnlyMessageReceiver"/>
        <messageReceiver mep="http://www.w3.org/2004/08/wsdl/in-out"
            class="org.apache.axis2.rpc.receivers.RPCMessageReceiver" />
    </messageReceivers>
</service>

<!-- http://localhost:9988/services/MyTestWebServiceOne?wsdl -->
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xmlns="http://xmlns.jcp.org/xml/ns/javaee"
	xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd"
	id="WebApp_ID" version="3.1">
	<display-name>MyTest_WebService_Server</display-name>
	<welcome-file-list>
		<welcome-file>index.jsp</welcome-file>
	</welcome-file-list>
	<servlet>
		<servlet-name>AxisServlet</servlet-name>
		<servlet-class>org.apache.axis2.transport.http.AxisServlet</servlet-class>
		<load-on-startup>1</load-on-startup>
	</servlet>
	<servlet-mapping>
		<servlet-name>AxisServlet</servlet-name>
		<url-pattern>/services/*</url-pattern>
	</servlet-mapping>
</web-app>
package lxw.webservice.server;

public class TestWebServiceOne {
	public String getServerReturn(String info){
		return info+"***************server return";
	}
}

若要发布多个WebService服务,可以使用<serviceGroup>包含多个<service>。

可以使用<operation>指定每一个方法,并为每一个方法指定对应的处理器。

<service name="HelloService">  
    <description>  
        Web Service例子  
    </description>  
    <parameter name="ServiceClass">  
        lxw.com.HelloService    
    </parameter>  
    <operation name="sayHello">  
        <messageReceiver class="org.apache.axis2.rpc.receivers.RPCMessageReceiver"/>  
    </operation>  
    <operation name="updateData">  
        <messageReceiver class="org.apache.axis2.rpc.receivers.RPCInOnlyMessageReceiver"/>  
    </operation>  
</service> 

b)发布方式二:打jar包的方式

——编写services.xml及对应服务类,得到服务类的class文件;

——建立一个文件夹,分别将两个文件放置到相应位置,如:D:\ws\ lxw\server\ServerTwo.class,D:\MEAT-INF\services.xml;

——在ws文件夹下运行命名:jar cvf ws.aar .(注意:最后面是空格+小数点);

——将得到的aar文件拷贝至工程的/WEB-INF/services下;

——修改web.xml,导入lib文件(同上),运行服务。

jar命令知识补充:

jar命令格式:jar {c t x u f }[ v m e 0 M i ][-C 目录]文件名...
其中{ctxu}这四个参数必须选选其一。[v f m e 0 M i ]是可选参数,文件名也是必须的。
-c 创建一个jar包
-t 显示jar中的内容列表
-x 解压jar包
-u 添加文件到jar包中
-f 指定jar包的文件名
-v 生成详细的报造,并输出至标准设备
-m 指定manifest.mf文件.(manifest.mf文件中可以对jar包及其中的内容作一些一设置)
-0 产生jar包时不对其中的内容进行压缩处理
-M 不产生所有文件的清单文件(Manifest.mf)。这个参数与忽略掉-m参数的设置
-i 为指定的jar文件创建索引文件
-C 表示转到相应的目录下执行jar命令,相当于cd到那个目录,然后不带-C执行jar命令

2、调用WebService的服务

a)调用方式1:wsdl2java生成客户端代码方式调用

——切换到axis2-1.6.2\bin目录下,cmd运行命令:wsdl2java.bat -uri http://localhost:9988/services/MyTestWebServiceOne?wsdl,生成客户端代码;

该命令可以添加可选命令,实现更具体的操作:

-o <path> : 指定生成代码的输出路径
-a : 生成异步模式的代码
-s : 生成同步模式的代码
-p <pkg> : 指定代码的package名称
-l <languange> : 使用的语言(Java/C) 默认是java
-t : 为代码生成测试用例
-ss : 生成服务端代码 默认不生成
-sd : 生成服务描述文件 services.xml,仅与-ss一同使用
-d <databinding> : 指定databingding,例如,adb,xmlbean,jibx,jaxme and jaxbri
-g : 生成服务端和客户端的代码
-pn <port_name> : 当WSDL中有多个port时,指定其中一个port
-sn <serv_name> : 选择WSDL中的一个service
-u : 展开data-binding的类
-r <path> : 为代码生成指定一个repository
-ssi : 为服务端实现代码生成接口类
-S : 为生成的源码指定存储路径
-R : 为生成的resources指定存储路径
–noBuildXML : 输出中不生成build.xml文件
–noWSDL : 在resources目录中不生成WSDL文件
–noMessageReceiver : 不生成MessageReceiver类

如:wsdl2java -uri http://localhost:9988/services/MyTestWebServiceOne?wsdl -s -p lxw.webservice.client -o build\client

——将生成的代码复制到客户端工程的对应包中,编写调用代码进行调用。

(此方法简单不易出错)

import org.apache.axis2.client.Options;
import org.apache.axis2.client.ServiceClient;
import lxw.webservice.server.MyTestWebServiceOneStub;
import lxw.webservice.server.MyTestWebServiceOneStub.GetServerReturn;
import lxw.webservice.server.MyTestWebServiceOneStub.GetServerReturnResponse;

public class TestWebserviceClient {
	public static void main(String[] args) throws Exception {
		MyTestWebServiceOneStub stub = new MyTestWebServiceOneStub("http://localhost:9988/services/MyTestWebServiceOne?wsdl");//反向生成类				
		ServiceClient serviceClient = stub._getServiceClient();//获取serviceClient 可以设置相关参数
		Options options = serviceClient.getOptions();
                GetServerReturn getSR = new GetServerReturn();//实例化对应调用方法
                getSR.setInfo("test");//设置参数
                GetServerReturnResponse response= stub.getServerReturn(getSR);//调用返回结果   
                String result = response.get_return();

                System.out.println("result:"+result);
	}
}

b)调用方式2:RPC远程调用

直接编写调用过程(此方法较为简洁,但容易出错)

import javax.xml.namespace.QName;
import org.apache.axis2.addressing.EndpointReference;
import org.apache.axis2.client.Options;
import org.apache.axis2.rpc.client.RPCServiceClient;
import org.apache.axis2.transport.http.HTTPConstants;

public class TestWebserviceClient2 {
	public static void main(String[] args) throws Exception {
		String url ="http://localhost:9988/services/MyTestWebServiceOne?wsdl";
		RPCServiceClient client = new RPCServiceClient(); 
		Options options = client.getOptions(); 
		
		//可以设置HttpClient的参数  
		/*MultiThreadedHttpConnectionManager connManager = new MultiThreadedHttpConnectionManager();
		connManager.getParams().setSoTimeout(600*1000); //10秒
		connManager.getParams().setConnectionTimeout(600*1000);
                HttpClient httpclient = newHttpClient(connManager);
                options.setProperty(HTTPConstants.CACHED_HTTP_CLIENT, httpclient );*/
        
		EndpointReference endpoint = new EndpointReference(url);//指定调用WebService的URL  
		options.setTo(endpoint); 
		options.setProperty(HTTPConstants.CHUNKED, Boolean.FALSE);
		options.setAction("http://server.webservice.lxw/getServerReturn");//设置命令空间(wsdl文档中的targetNamespace)和方法名称 的组合)
		//options.setTimeOutInMilliSeconds(50000000L);		
		//options.setProperty(HTTPConstants., 600000);	
		//options.setProperty(HTTPConstants.SO_TIMEOUT, 600*1000);
		options.setProperty(HTTPConstants.SO_TIMEOUT, 600*1000);
		
		
                Object[] parameters = new Object[] {"hello world"};// 指定方法的参数值
		Class<?>[] returnTypes = new Class[]{String.class};//返回值类型
                // 创建服务名称
                // 1.namespaceURI - 命名空间地址 (wsdl文档中的targetNamespace)
                // 2.localPart - 服务视图名 (wsdl文档中operation的方法名称)
		QName qname = new QName("http://server.webservice.lxw","getServerReturn");
        
		Object[] response = client.invokeBlocking(qname, parameters,returnTypes);//调用方法, 传递参数,获取服务返回结果集
                String result = response[0].toString();
                System.out.println(result);
	}
}

c)调用方式3:document方式调用

相对简洁灵活

import org.apache.axiom.om.OMAbstractFactory;
import org.apache.axiom.om.OMElement;
import org.apache.axiom.om.OMFactory;
import org.apache.axiom.om.OMNamespace;
import org.apache.axis2.addressing.EndpointReference;
import org.apache.axis2.client.Options;
import org.apache.axis2.client.ServiceClient;

public class TestWebserviceClient3 {
	public static void main(String[] args) throws Exception {
		ServiceClient client = new ServiceClient();
		String url ="http://localhost:9988/services/MyTestWebServiceOne?wsdl";
		Options options = new Options();
		EndpointReference targetEPR = new EndpointReference(url);
		options.setTo(targetEPR);
		options.setAction("http://server.webservice.lxw/getServerReturn");
		client.setOptions(options);
		OMFactory omFactory = OMAbstractFactory.getOMFactory();	
		
                OMNamespace namespace =omFactory.createOMNamespace("http://server.webservice.lxw", "");// 命名空间 
                OMElement method =omFactory.createOMElement("getServerReturn", namespace);//指定方法
                OMElement infoElement  = omFactory.createOMElement("info",namespace);//指定方法的参数
                infoElement.setText("hello");
                method.addChild(infoElement);
                method.build();
        
                OMElement result = client.sendReceive(method);//远程调用web服务
                System.out.println(result);
	}
}

 


参考链接:

https://www.cnblogs.com/xdp-gacl/p/4048937.html
https://blog.csdn.net/qq_35712358/article/details/71244342
https://www.cnblogs.com/qingguang/p/4438132.html
https://blog.csdn.net/zhangmeng_07/article/details/54663605
 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值