webService的初步认识和简单用例

本文详细介绍WebService的概念、原理及实现步骤,包括服务端发布接口服务、客户端远程调用接口服务的具体操作,适合初学者快速上手。

一、什么是webService?

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

几个基本概念:

SOAP:简单对象存取协议,是webService的通信协议,是针对xml文档形式的调用方法的规范,可支持不同的底层接口,如http;

WSDL:是一个xml文档, 用于说明一组soap消息,以及如何交换这些消息;

UDDI:是一个主要针对Web服务供应商和使用者的新项目,是一种根据wsdl文件(描述文档)来引导客户端查找响应服务的机制。它是利用SOAP消息机制(标准的XML/HTTP)来发布,编辑,浏览以及查找注册信息。它采用XML格式来封装各种不同类型的数据,并且发送到注册中心或者由注册中心来返回需要的数据。

一言以蔽之:webService是一种典型,成熟的远程服务调用技术规范。如网站对天气预报接口的接入,对列车时刻表、航班的接口接入等。

 

二、服务端简单示例

1)服务端服务接口模拟

看之前网上的示例,都是一个接口服务对应一个wsdl文件的,然而我考虑到:如果会有不止一个接口呢?该咋办?——其实,当然我可以一个接口实现类对应一个wsdl文件,并且也测试过没问题,但现在我想要发布多个接口服务,但只生成一个wsdl文件。

实现这种效果很简单,只需用一个实现类,该实现类同时实现若干个接口即可。但这样会造成耦合(下面就来测试这种,具体应用中,一般是某一类服务对应于一个接口,此时还是要用到一个接口对应一个wsdl文件的模式。)

 

接口一:

@WebService
public interface IService {
	
	public void sayHello(@WebParam(name="username") String name);
	
	public int calculatr(int m, int n);
}

 接口二:

@WebService
public interface IService2 {
	public void getInfo(@WebParam(name="person") Person person);
}

其中,Person类是一个pojo,

public class Person implements Serializable{//因为要用于远程传输,所以需要序列化
	
	private static final long serialVersionUID = 1L;
	private String name;
	private int age;
	private String gender;
	public String getName() {
		return name;
	}
	public void setName(String name) {
		this.name = name;
	}
	public int getAge() {
		return age;
	}
	public void setAge(int age) {
		this.age = age;
	}
	public String getGender() {
		return gender;
	}
	public void setGender(String gender) {
		this.gender = gender;
	}
	@Override
	public String toString() {
		return "Pserson [name=" + name + ", age=" + age + ", gender=" + gender
				+ "]";
	}
	
}

  接口的实现类(这里我测试2个接口对应1个实现类,即生成一个wsdl文件,但现实中可能并不推荐这么做。。)

@WebService  //注意:实现类要有该注解,才能被发布
public class MutiServiceImpl implements IService, IService2 {

	@Override
	public void getInfo(Person person) {
		System.out.println("该人员的信息:" + person);
	}

	@Override
	public void sayHello(String name) {
		System.out.println("Hello, my name is " + name);
	}

	@Override
	public int calculatr(int m, int n) {
		return m * n;
	}

}

 服务端接口服务的发布:

public class ServicePublish {
	
	public static void main(String[] args) {
		String address = "http://localhost:9001/Service/service";
//address由自己来指定  不过要符合规范 http://ip地址:端口/服务名/具体服务
//第二个参数必须是具体实现类
		Endpoint.publish(address, new MutiServiceImpl());
		System.out.println("webService之服务端服务发布成功!");
	}
	
}

 运行main方法,可以看到打印信息,说明接口服务发布成功!(其实测试webService不是非得建立web project,普通的工程即可~~)

 

我们不妨在浏览器上输入刚刚发布的地址:http://localhost:9001/Service/service?wsdl(要加上?wsdl),即可看到一个自动生成的xml格式的描述文件:

This XML file does not appear to have any style information associated with it. The document tree is shown below.
<!--
 Published by JAX-WS RI (http://jax-ws.java.net). RI's version is JAX-WS RI 2.2.9-b130926.1035 svn-revision#5f6196f2b90e9460065a4c2f4e30e065b245e51e. 
-->
<!--
 Generated by JAX-WS RI (http://jax-ws.java.net). RI's version is JAX-WS RI 2.2.9-b130926.1035 svn-revision#5f6196f2b90e9460065a4c2f4e30e065b245e51e. 
-->
<definitions xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd" xmlns:wsp="http://www.w3.org/ns/ws-policy" xmlns:wsp1_2="http://schemas.xmlsoap.org/ws/2004/09/policy" xmlns:wsam="http://www.w3.org/2007/05/addressing/metadata" xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/" xmlns:tns="http://the_service/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns="http://schemas.xmlsoap.org/wsdl/" targetNamespace="http://the_service/" name="MutiServiceImplService">
<types>
<xsd:schema>
<xsd:import namespace="http://the_service/" schemaLocation="http://localhost:9001/Service/service1?xsd=1"/>
</xsd:schema>
</types>
<message name="getInfo">
<part name="parameters" element="tns:getInfo"/>
</message>
<message name="getInfoResponse">
<part name="parameters" element="tns:getInfoResponse"/>
</message>
<message name="sayHello">
<part name="parameters" element="tns:sayHello"/>
</message>
<message name="sayHelloResponse">
<part name="parameters" element="tns:sayHelloResponse"/>
</message>
<message name="calculatr">
<part name="parameters" element="tns:calculatr"/>
</message>
<message name="calculatrResponse">
<part name="parameters" element="tns:calculatrResponse"/>
</message>
<portType name="MutiServiceImpl">
<operation name="getInfo">
<input wsam:Action="http://the_service/MutiServiceImpl/getInfoRequest" message="tns:getInfo"/>
<output wsam:Action="http://the_service/MutiServiceImpl/getInfoResponse" message="tns:getInfoResponse"/>
</operation>
<operation name="sayHello">
<input wsam:Action="http://the_service/MutiServiceImpl/sayHelloRequest" message="tns:sayHello"/>
<output wsam:Action="http://the_service/MutiServiceImpl/sayHelloResponse" message="tns:sayHelloResponse"/>
</operation>
<operation name="calculatr">
<input wsam:Action="http://the_service/MutiServiceImpl/calculatrRequest" message="tns:calculatr"/>
<output wsam:Action="http://the_service/MutiServiceImpl/calculatrResponse" message="tns:calculatrResponse"/>
</operation>
</portType>
<binding name="MutiServiceImplPortBinding" type="tns:MutiServiceImpl">
<soap:binding transport="http://schemas.xmlsoap.org/soap/http" style="document"/>
<operation name="getInfo">
<soap:operation soapAction=""/>
<input>
<soap:body use="literal"/>
</input>
<output>
<soap:body use="literal"/>
</output>
</operation>
<operation name="sayHello">
<soap:operation soapAction=""/>
<input>
<soap:body use="literal"/>
</input>
<output>
<soap:body use="literal"/>
</output>
</operation>
<operation name="calculatr">
<soap:operation soapAction=""/>
<input>
<soap:body use="literal"/>
</input>
<output>
<soap:body use="literal"/>
</output>
</operation>
</binding>
<service name="MutiServiceImplService">
<port name="MutiServiceImplPort" binding="tns:MutiServiceImplPortBinding">
<soap:address location="http://localhost:9001/Service/service1"/>
</port>
</service>
</definitions>

这里顺便简单讲一下这个wsdl文件的一些关键字段 。

1)definitions元素——wsdl文件的根元素

2)type元素——作为一容器,定义了自定义的特殊数据类型,在声明消息部分(有效负载)的时候,messages定义使用了types元素中定义的数据类型与元素。

3)Message元素描述了Web服务的有效负载。相当于函数调用中的参数和返回值。

4)PortType元素定义了Web服务的抽象接口,它可以由一个或者多个operation元素,每个operation元素定义了一个RPC样式或者文档样式的Web服务方法,相当于类接口的名称。

5)Operation元素要用一个或者多个messages消息来定义它的输入、输出以及错误,相当于接口中包含的函数。

6)Binding元素将一个抽象的portType映射到一组具体的协议(SOAP或者HTTP)、消息传递样式(RPC或者document)以及编码样式(literal或者SOAP encoding)。

7)Service元素包含一个或者多个Port元素,每个Port元素对应于一个web服务

 

三、客户端简单示例(开另一个工程,不一定是web工程)

生成了wsdl文件之后,我们就需要根据该wsdl文件【自动】生成客户端的调用代码了。

一般而言,使用Jdk1.6+自带的命令会比较简单。(前提是你已配置好jdk环境变量)

具体命令格式为:

wsimport -s "src目录" -p “生成类所在包名” -keep “wsdl发布地址”

在本例中,为 wsimport -s  E:\xxx\the_client\src -p org.webservice.client -keep http://localhost:9001/Service/service?wsdl  (因为服务端和客户端都在同一台机器,所以直接用localhost,如果不是同一台机器,则客户端需要准确输入服务端的地址)

成功执行完命令之后,刷新会发现多了如下类:



 接下来,我们就开始远程调用测试了:

public class ClientSub {
	public static void main(String[] args) {
		try {
			MutiServiceImpl impl = new MutiServiceImplService().getMutiServiceImplPort();
			
			int x = impl.calculatr(30, 2);
			System.out.println("计算结果:" + x);
			
			Person person = new Person();
			person.setAge(23);
			person.setGender("男");
			person.setName("Karl");
			impl.getInfo(person);
			
			impl.sayHello("Connor");
			
		} catch (Exception e) {
			e.printStackTrace();
		}
	}
}

运行该服务的订阅类,会发现分别在服务端和客户端的控制台打印如下: 

服务端:



 客户端:



 

说明:利用webService来进行远程调用接口服务成功!

### 回答1: Java中使用JAX-WS编写Web Service接口的步骤如下: 1. 创建Web Service接口类,使用@WebService注解标注接口类 2. 创建Web Service接口实现类,实现接口类中的方法 3. 创建Endpoint类,使用Endpoint.publish()方法发布Web Service 在这个子中我们定义了一个简单webservice接口叫做HelloWorldService,它有一个方法叫做sayHello,返回一个字符串。 ```java import javax.jws.WebMethod; import javax.jws.WebService; @WebService public interface HelloWorldService { @WebMethod String sayHello(String name); } ``` 实现类 ```java import javax.jws.WebService; @WebService(endpointInterface = "com.example.helloworld.HelloWorldService") public class HelloWorldServiceImpl implements HelloWorldService { @Override public String sayHello(String name) { return "Hello, " + name + "!"; } } ``` 发布webservice ```java import javax.xml.ws.Endpoint; public class HelloWorldPublisher { public static void main(String[] args) { Endpoint.publish("http://localhost:8080/ws/hello", new HelloWorldServiceImpl()); } } ``` 调用webservice: ```java import javax.xml.namespace.QName; import javax.xml.ws.Service; import java.net.URL; public class HelloWorldClient { public static void main(String[] args) throws Exception { URL url = new URL("http://localhost:8080/ws/hello?wsdl"); QName qname = new QName("http://helloworld.example.com/", "HelloWorldServiceImplService"); Service service = Service.create(url, qname); HelloWorldService hello = service.getPort(HelloWorldService.class); System.out.println(hello.sayHello("John")); } } ``` 上面的示发布了一个webservice接口到本地的8080端口。然后客户端通过调用这个接口的sayHello方法返回 "Hello, John!" ### 回答2: Java编写WebService接口的步骤如下: 1. 创建一个Java项目,并在项目中引入相关的WebService库,如Apache CXF或JAX-WS。 2. 在项目中创建一个新的Java类,作为WebService的实现类。该类需要使用@WebService注解进行标注,并且定义WebService的方法。 3. 在方法上使用@WebMethod注解进行标注,指定该方法对外提供的WebService接口。 4. 根据需要,在方法的参数返回值上使用@WebParam注解进行标注,指定参数返回值的名称。 5. 在方法的实现中,编写具体的业务逻辑,并将结果返回。 6. 编译并部署该Java项目,使之成为一个可供外部调用的WebService接口。 调用Java编写的WebService接口的用如下: 1. 创建一个Java项目,并在项目中引入相关的WebService库,如Apache CXF或JAX-WS。 2. 根据WebService接口的WSDL文档,生成客户端的Java代码。可以使用wsimport命令行工具或IDE插件进行代码生成。 3. 在代码中创建一个WebService的代理对象,并通过代理对象调用WebService接口的方法。 4. 根据方法的参数返回值,设置相应的参数并调用方法。 5. 处理方法的返回值,并根据业务需求进行后续处理。 需要注意的是,调用WebService接口时可能需要传递认证信息或使用安全协议。在调用时,需要根据具体接口的需求进行设置。此外,还需要处理WebService接口调用可能出现的异常情况,如网络连接异常或服务器不可用等。 ### 回答3: Java编写WebService接口是通过使用Java中的WebService框架来实现的。下面是一个示: 1. 首先,需要定义WebService接口。可以使用Java的注解方式来定义WebService接口,并指定接口的名称、命名空间、方法等。如: ```java import javax.jws.WebMethod; import javax.jws.WebService; @WebService(name = "HelloWebService", targetNamespace = "http://www.example.com/") public interface HelloWebService { @WebMethod String sayHello(String name); } ``` 2. 接下来,需要实现WebService接口。创建一个实现类,并实现接口中定义的方法。如: ```java @WebService(endpointInterface = "com.example.HelloWebService") public class HelloWebServiceImpl implements HelloWebService { @Override public String sayHello(String name) { return "Hello, " + name + "!"; } } ``` 3. 构建一个WebService服务,并发布在一个特定的地址上。可以使用Java内置的工具类Endpoint来创建发布WebService服务。如: ```java import javax.xml.ws.Endpoint; public class HelloWebServicePublisher { public static void main(String[] args) { String url = "http://localhost:8080/hello"; Endpoint.publish(url, new HelloWebServiceImpl()); System.out.println("WebService is published at: " + url); } } ``` 4. 编译运行以上代码。 以上就是Java编写WebService接口的步骤。 调用WebService接口可以通过Java的代理类来完成。代理类可以通过Java自带的工具wsimport来生成。如: 1. 打开命令行窗口,进入到存放生成代理类的目录。 2. 运行wsimport命令,指定服务的WSDL地址生成代理类的目标包路径。如: ``` wsimport -p com.example.wsclient -s . http://localhost:8080/hello?wsdl ``` 3. 运行生成的代理类来调用WebService接口。如: ```java import com.example.wsclient.HelloWebService; import com.example.wsclient.HelloWebServiceImplService; public class HelloWebServiceClient { public static void main(String[] args) { HelloWebServiceImplService service = new HelloWebServiceImplService(); HelloWebService port = service.getHelloWebServiceImplPort(); String result = port.sayHello("John"); System.out.println(result); } } ``` 以上是Java调用WebService接口的步骤。需要注意的是,调用时要使用代理类中的端口对象进行方法调用。 希望以上回答对您有帮助!
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值