WebService是什么?
一种跨编程语言和跨操作系统平台的一种远程调用技术。
跨编程语言与跨平台,指的是你服务端采用java编写,你的客户端可以采用其他的编程语言编写,反过来同样的道理。 而跨平台是指可以在不同的操作系统上运行。
远程调用,通俗可以理解为在一台计算机上调用另一台计算机上的程序。如:天气预报系统,京东,淘宝等。
表面上看,WebService是一个应用程序向外界提供了一个接口API,能通过编程的方法去调用这个应用程序。这个应用程序叫做服务端,调用这个应用程序的叫客户端。 更深层次上看,WebService是建立可互操作的分布式的应用程序的新平台,是一个标准,定义了程序如何在Web上互相操作。
WebService平台技术。
XML+XSD,SOAP,WSDL
采用xml格式进行数据的封装, xml解决了数据表示,但是没有一套标准的数据类型,怎么去扩展这套数据类型,如:整型代表多少位,这对实现互操性很重要。XSD(XML Schema)就是专门解决这个问题的。 WebService就是采用XSD作为数据类型系统的。
WebService采用http协议发送请求和接受结果时,发送的请求内容和结果内容都采用XML进行数据的封装,并增加了一些特定的HTTP消息头,用以说明http消息的内容模式。这些特定的HTTP消息头和XML内容就是SOAP协议。SOPA提供了标准的RPC方法调用WebService。 SOAP协议=HTTP协议+XML数据格式。
WSDL是通过xml的形式告诉这个WebService该怎么去调用。(对外提供的服务,方法,参数等), 比如:买东西要知道有什么东西能买之类的。
WebService工作原理
对客户端来说,我们给WebService客户端API传递wsdl文件的url地址,这些api会创建出底层的代理类,调用这些代理类,去访问WebService服务。代理类把客户端的调用方法变成soap格式的请求再通过http协议发出去,并将接受到的soap数据变成返回值返回。
对服务端来说,WebService框架本质上就是一个Servlet,当远程调用客户端给他通过http发送soap格式的请求数据时,分析这个数据,决定调用那个方法,去查找创建这个对象调用方法,再将方法返回的结果包装成soap格式,通过http响应给客户端。
示例Demo
1.服务端示例
import javax.jws.WebService;
/*
注解 @WebService标注了这个接口的方法公开为Web服务。
如果想屏蔽某个方法,可以使用方法注解 @Method的exclued=true
通常将把公开为Web服务的接口叫做SEI(服务端点接口)
*/
@WebService
public interface IHelloService {
Customer selectMaxAgesStudent(Customer c1,Customer c2);
Customer selectMaxLongNameStudent(Customer c1,Customer c2);
}
2.实现类
import javax.jws.WebService;
/*
实现类
如果你的实现类还实现了其他的接口,那么你需要在实现类上使用WebService注解
的endpointInterface属性制定那个接口是SEI(服务端点接口) 需要全类名
*/
@WebService
public class HelloServiceImpl implements IHelloService{
@Override
public Customer selectMaxAgesStudent(Customer c1, Customer c2) {
if(c1.getBirthday().getTime()>c2.getBirthday().getTime()){
return c2;
}else{
return c1;
}
}
@Override
public Customer selectMaxLongNameStudent(Customer c1, Customer c2) {
if(c1.getName().length()>c2.getName().length()){
return c1;
}else{
return c2;
}
}
}
3.Customer类
import javax.xml.bind.annotation.XmlRootElement;
import java.util.Date;
/*
这个类是公开为web服务的接口中的参数类型和返回值,
注解的作用是告诉CXF如何在xml和java之间处理
*/
@XmlRootElement(name="Customer")
public class Customer {
private long id;
private String name;
private Date birthday;
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;
}
}
4.发布web服务
import javax.xml.ws.Endpoint;
public class SoapServer {
public static void main(String[] args) {
Endpoint.publish("http://127.0.0.1:8080/helloService",new HelloServiceImpl());
}
}
或
public class SoapServer {
public static void main(String[] args) {
JaxWsServerFactoryBean soapFactoryBean=new JaxWsServerFactoryBean();
//在输入输出拦截器集合中添加日志拦截器
soapFactoryBean.getInInterceptors().add(new LoggingInInterceptor());
soapFactoryBean.getOutInterceptors().add(new LoggingOutInterceptor());
//传入的是实现类
soapFactoryBean.setServiceClass(HelloServiceImpl.class);
soapFactoryBean.setAddress("http://127.0.0.1:8080/helloService");
soapFactoryBean.create();
}
}
5.查看wsdl
http://127.0.0.1:8080/helloService?wsdl
分析wsdl的成分
(1)definitions 根元素
name:为公开的web接口的实现类+Service
targetNamespace:指定目标的名称空间 它的值被xmlns:tns属性作为值
可以使用@WebService注解的targetNamespace属性指定自己想要的名称空间
(2)types 数据类型定义的容器
(3)message 将方法参数和响应结果(方法返回值),受检查的异常信息封装为消息
(4)portType 此元素指定web服务的端口类型 name 为web服务的接口的实现类名 子元素制定了去操作那个方法
(5)binding 将最终的端点服务绑定到SOAP协议上 (关系)
(6)service name与根元素name相同 WEB服务的实现类+Service
子元素port为name属性指定port名称 子元素location为web服务地址。
客户端调用示例
用CXF将wsdl文件转换成java代码
命令:wsdl2java -p 包名 -d G:\生成的.java文件存放地方 url
然后在G盘下生成
文件
其中package-info.java和ObjectFactory.java是JAXB(java xml binding)所需要的,HelloServiceImplService.java继承自
java.xml.ws.Service,提供客户端Wsdl视图 其他的是方法 参数,web服务接口等。
public class SoapClient {
public static void main(String[] args) throws Exception {
/*
在CXF中使用JaxWsProtProxyfactoryBean(客户端代理工厂调用服务端web)
*/
JaxWsProxyFactoryBean soapFactoryBean=new JaxWsProxyFactoryBean();
soapFactoryBean.setAddress("http://127.0.0.1:8080/helloService");
soapFactoryBean.setServiceClass(HelloServiceImpl.class);
Object o=soapFactoryBean.create();
HelloServiceImpl helloService= (HelloServiceImpl) o;
Customer c1=new Customer();
c1.setId(1);
c1.setName("A");
GregorianCalendar calendar=(GregorianCalendar)GregorianCalendar.getInstance();
calendar.setTime(new SimpleDateFormat("yyyy-MM-dd").parse("1956-03-15"));
c1.setBirthday(new XMLGregorianCalendarImpl(calendar));
Customer c2=new Customer();
c2.setId(2);
c2.setName("B");
GregorianCalendar calendar1= (GregorianCalendar) GregorianCalendar.getInstance();
calendar1.setTime(new SimpleDateFormat("yyyy-MM-dd").parse("1996-03-05"));
c2.setBirthday(new XMLGregorianCalendarImpl(calendar1));
System.out.println(helloService.selectMaxAgesStudent(c1,c2).getName());
}
}