一 webService
1.1 webservcie
webservice是一种跨操作系统和跨语言的数据调用、数据交换的一种服务技术。用于网络通信,多台机器之间的数据交互。
最大优点:webservice最大的好处是客户端与服务端语言的兼容性及交互时候可以传递对象。
1.2 webservice与socket的区别
1. socket是在网络中的数据传输层,采用的是TCP/UDP协议,webservice是属于应用层,采用的是http协议
2. socket建立是长连接,webservice建立的是短连接(调用服务时建立连接,调用完毕后断开连接)
1.3 wsdl文档
1.3.1 定义
定义:web services description language,用来描述web服务的xml格式的信息。
1.3.2 作用
作用:通过wsdl说明书,就可以描述webservice服务端对外发布的服务;
1.3.3 文档格式
文档格式:
Service:指定服务所发布的名称,包括相关端口的集合,包括其关联的接口、操作、消息等。
Binding:指定消息传递的格式,特定端口类型的具体协议和数据格式规范,通过binding指向portType
portType: 指明服务器的接口,描述 web service可被执行的操作方法,以及相关的消息,并且通过operation绑定相应的in和out的消息:其中in表示参数,out表示返回值,,
message: 定义了多个SOAP消息,每个方法通常都有2个message标签,name属性分别是xxx和xxxResponse。
types: 定义了服务的namespace和关键信息的类型(方法的参数类型和返回值的类型)
1.3.4 阅读方式
WSDL文档应该从下往上阅读。
1.先看service标签,看相应port的binding属性,然后通过值查找上面的binding标签。
2.通过binding标签可以获得具体协议等信息,然后查看binding的type属性
3.通过binding的type属性,查找对应的portType,可以获得可操作的方法和参数、返回值等。
4.通过portType下的operation标签的message属性,可以向上查找message获取具体的数据参数信息
1.4 客户端接口targetnamespace的注意事项
客户端接口调用中的namespance,targetnamespance要写成:包.类名的反缀形式
targetNamespace:指定你想要的名称空间,默认是使用接口实现类的包名的反缀
二 webService的案例-服务端代码
2.1 编写服务端
2.2 编写webservice的发布类
2.2.1 定义发布接口speaker
package com.bonc.xj.webservice;
import javax.jws.WebService;
/**
* 定义服务的接口
* @author Beauxie
*
*/
@WebService//此注解用在类上指定将此类发布成一个WebService
public interface Speaker {
String sayHello(String name);
}
2.2.2 定义发布接口实现类Person
注意:接口和实现类中必须用@WebService注解,并且在实现类的注解中必须指定endpointInterface属性的值为接口的全限定名
package com.bonc.xj.webservice.impl;
/**
* @ClassName: Person
* @Description: TODO
* @Author: liujianfu
* @Date: 2021/03/18 10:26:08
* @Version: V1.0
**/
import com.bonc.xj.webservice.Speaker;
import javax.jws.WebService;
/**
* 定义服务的实现类
* @author Beauxie
*/
@WebService(endpointInterface="com.bonc.xj.webservice.Speaker")
public class Person implements Speaker {
public String sayHello(String name) {
return "Hello,"+name+"我在美丽的新疆吉木萨尔!";
}
}
2.3 编写发布服务类
//1.定义发布的地址:端口号,发布的上下文路径,自己定义
String url = "http://localhost:8002/ws-demo";
package com.bonc.xj;
import com.bonc.xj.webservice.impl.Person;
import javax.xml.ws.Endpoint;
/**
* Hello world!
*
*/
public class ServerApp
{
public static void main( String[] args )
{
//1.定义发布的地址:端口号,发布的上下文路径,自己定义
String url = "http://localhost:8002/ws-demo";
//2.发布服务
//第一个参数是指定你要发布的地址,第二个参数是你要发布的服务对象
Endpoint.publish(url, new Person());
System.out.println("服务器已启动");
System.out.println( "Hello World!" );
}
}
启动服务:
然后打开浏览器访问http://localhost:8002/ws-demo?wsdl,只要在客户端浏览器能看以下WSDL文档,说明服务发布成功:
2.4 编写客户端
1.在这个服务端工程下,创建一个调用的客户端,这个客户端是和服务端在一个工程下,代码如下:
package com.bonc.xj;
import com.bonc.xj.webservice.Speaker;
import javax.xml.namespace.QName;
import javax.xml.ws.Service;
import java.net.MalformedURLException;
import java.net.URL;
/**
* Hello world!
*
*/
public class ClientApp
{
public static void main( String[] args ) throws MalformedURLException {
//1.声明所发布的服务对应的wsdl地址
URL url=new URL("http://localhost:8002/ws-demo?wsdl");
//2.声明所要调用的Qname
QName qname=new QName("http://impl.webservice.xj.bonc.com/", "PersonService");
//3.创建客户端的服务代理对象
Service service=Service.create(url,qname);
Speaker speaker = service.getPort(Speaker.class);
//4.调用服务的方法
String str=speaker.sayHello("Beauxie");
System.out.println(str);
}
}
2. QName qname=new QName("http://impl.webservice.xj.bonc.com/", "PersonService"); 这里面的两个参数,要参考发布文档中的targetnamespace 和name这个两个参数,两个参数都不能瞎写,
其实表达的意思就是要访问服务端下的:com.bonc.xj.webservice.impl 的Person这个类(service后缀要加上,变为PersonSevice)
3. 执行结果:
三 webService的案例-客户端代码
虽然在上面服务端编写客户端代码也能调通,但是为了层次分明,和具有说服力,这里将单独再建一个客户端的工程,去调用服务端的服务接口。
3.1 webservice客户端工程
3.2 客户端speaker 接口
1.这里的接口
@WebService(targetNamespace = "http://webservice.xj.bonc.com/") 参考服务端发布的wsdl文档中,<wsdl:import 中的namespace的值,这里配置为http://webservice.xj.bonc.com/ ,其实就是映射成服务端
这个接口speaker所在的包.类的绝对路径。
<wsdl:import location="http://localhost:8002/ws-demo?wsdl=Speaker.wsdl" namespace="http://webservice.xj.bonc.com/"> </wsdl:import>
2.图片
3.详情代码
客户端需要新建一个speaker的接口:和服务端的speaker接口一致
package com.bonc.ws.client.service;
import javax.jws.WebService;
/**
* 定义服务的接口
* @author Beauxie
*
*/
/*
这个接口中targetnamespace的配置原则为:
参考服务端发布的wsdl文档中,wsdl=speaker.wsdl 中的namespace的值,这里配置为http://webservice.xj.bonc.com/ ,其实就是映射成服务端
这个接口speaker所在的包.类的绝对路径。
<wsdl:import location="http://localhost:8002/ws-demo?wsdl=Speaker.wsdl" namespace="http://webservice.xj.bonc.com/"> </wsdl:import>
*/
@WebService(targetNamespace = "http://webservice.xj.bonc.com/")
public interface Speaker {
String sayHello(String name);
}
3.3 客户端调用接口
1.这里new QNam(x,x)参数的配置:
QName qname=new QName("http://impl.webservice.xj.bonc.com/", "PersonService"); 里面的参数配置原则:QName中两个参数所对应wsdl文档中参数:
这里的:
package com.bonc.ws.client;
import com.bonc.ws.client.service.Speaker;
import javax.xml.namespace.QName;
import javax.xml.ws.Service;
import java.net.MalformedURLException;
import java.net.URL;
/**
* Hello world!
*
*/
public class App2
{
public static void main( String[] args ) throws MalformedURLException {
//1.声明所发布的服务对应的wsdl地址
URL url=new URL("http://localhost:8002/ws-demo?wsdl");
//2.声明所要调用的Qname
QName qname=new QName("http://impl.webservice.xj.bonc.com/", "PersonService");
//3.创建客户端的服务代理对象
Service service=Service.create(url,qname);
Speaker speaker = service.getPort(Speaker.class);
//4.调用服务的方法
String str=speaker.sayHello("Beauxie");
System.out.println(str);
}
}
调用结果:
参考地址:https://blog.csdn.net/BeauXie/article/details/52851862
未完待续,下一篇:使用wsimport命令生成webservice的客户端接口