初入WebService

什么是WebService?

  一种基于Web的服务,服务端提供一些资源让客户端进行访问,获取一些公共的数据。比如天气预报,股票信息,手机归属地查询等等。

WebService是一种跨平台,跨语言的规范。

气象局负责将收集的每天的天气信息,并将这些信息暴露出来,各大站点的应用去调用网络接口得到当天或者未来几天的天气情况,然后以不同形式展示出来。

网站提供了天气预报的信息,其实网站本身什么都没有做,只是调用了一下远程接口。这个就是WebService的典型应用。

WebService组织图

Web服务的几个重要术语:

WSDL(Web Services Description Language):Web服务描述语言。一个XML文档,WSDL定义了Web Service 的名称、处理服务的方法、请求的参数及返回的数据格式。一个WebService对应唯一一个wsdl文档。

SOAP(Simple Object Access Protocol):简单对象传输协议。一个基于HTTP和XML的协议,用于在Web上的应用程序交换结构化的数据。

SEI(WebService Endpoint Interface):WebService服务端用来处理请求的接口。

CXF(Celtix + XFire):一个Apache的用于开发webService服务器和客户端框架。

WSDL的基本结构:

Types元素

  数据类型定义的容器
Message元素
  通信消息的数据结构的抽象类型定义
PorType元素
  可以描述一个Web Service可被执行的操作以及相关的消息
Binding元素
  特定端口类型的具体协议和数据格式规范的绑定
Service元素
  相关服务访问点的集合

SOAP概述:

SOAP(SImple Object Access Protocol,简称对象访问协议)基于XML的,用于在分布式环境下交换信息的轻量级协议。
SOAP 1.2规范与2003年6月24日被发布为W3C推荐标准
SOAP的优点
与厂商无关
相对于平台独立
相对与操作系统独立
相对与编程语言独立

开发WebService:

 WebService组成

服务器端:提供WebService的服务器端。(Java开发)
客户端:调用远程WebServiec的客户端应用程序。可以在任何系统下使用任何语言调用。

开发WebService分为两种方式

JAX-WS方式:Web标准服务
CXF方式:基于CXF框架开发

JAX-WS方式开发WebService:

开发步骤:
创建一个JavaProject项目
添加WebService的接口,使用@WebService和@WebMethod注解修饰类。
添加实现WebService接口的类,使用@WebService修饰,并指定EndpointInterface属性到接口的完整类名。
添加一个Endpoint来发布WebService。

package com.webservice.server;
import java.util.List;
import java.util.Set;
import javax.jws.WebMethod;
import javax.jws.WebService;
@WebService
public interface WeatherService {
    @WebMethod
    public Set<String> getProvinces();
    @WebMethod
    public List<String> getCitys(String proName);
}
package com.webservice.server;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;

import javax.jws.WebService;

@WebService(endpointInterface="com.webservice.server.WeatherService")
public class WeatherServiceImpl implements WeatherService {
    private static Map<String, ArrayList<String>> provincies;
    static{
        provincies = new HashMap<String, ArrayList<String>>();
        ArrayList<String> beijing = new ArrayList<>();
        beijing.add("海淀区");
        beijing.add("朝阳区");
        provincies.put("北京", beijing);

        ArrayList<String> guangdong = new ArrayList<>();
        guangdong.add("广州");
        guangdong.add("深圳");
        guangdong.add("东莞");
        provincies.put("广东省", guangdong);

        ArrayList<String> hunan = new ArrayList<>();
        hunan.add("长沙");
        hunan.add("永州");
        provincies.put("湖南省", hunan);
    }
    @Override
    public Set<String> getProvinces() {
        return provincies.keySet();
    }

    @Override
    public List<String> getCitys(String proName) {
        return provincies.get(proName);
    }

}
package com.webservice.server.test;

import javax.xml.ws.Endpoint;

import com.webservice.server.WeatherServiceImpl;

public class TestWebService {
    public static void main(String[] args) {
        String address = "http://localhost:9999/weather/getweathers";
        //发布webService
        Endpoint.publish(address, new WeatherServiceImpl());
        System.out.println("发布成功!");
    }
}

WebService常用注解:

@WebService(必须的)
修饰一个类或者接口为一个WebSevice,如果有接口,必须提供endpointInterface指定接口名称,否则会报警告。
@WebMethod(可省略)
修饰一个方法为一个Web方法。可以被远程调用。也可以通过exclude=true来排除某个方法。
@WebParm(可省略)
修饰生成wsdl文件中方法的参数名称。

现在我们已经发布了WebService那么怎么调用它呢?

首先我们进入cmd 然后进入到项目中src文件夹中使用wsimport工具从WSDL文件生成客户端调用所需的Java类。

wsimport是JDK中bin中所带的工具,所以需要配置环境变量

G:\daima\上课代码\webService\webServiceClient\src>wsimport -p com.webservice.demo1 -keep http://localhost:9999/weather/getweathers?wsdl

com.webservice.demo1 是我们指定生成的包名。http://localhost:9999/weather/getweathers?wsdl发布的地址

 生成之后就是这个样子的,我们刷新eclipse中的项目发现多了一个包

这个玩意就是刚才生成的,那么我们怎么使用呢?

WeatherService weatherService = new  WeatherServiceImplService().getWeatherServiceImplPort();
        List<String> lists = weatherService.getProvinces();

在网上已经有人家提供的接口我们直接可以调用,当我们JAVA调用的时候遇见.net的怎么解决呢。

首先我们将他接口中的wsdl那些xml保存到本地的src然后我们需要将xml中的

<s:element ref="s:schama"  />
<s:any />

改成

<s:any minOccurs="2" maxOccurs="2" />

然后直接调用本地文件生成JAVA文件即可

G:\daima\上课代码\webService\webServiceClient\src>wsimport -p . -keep G:\daima\上课代码\webService\webServiceClient\src\weather.wsdl

p后面那个点指的是根据源文件生成包名。

Apche CXF WebService框架

CXF是apache旗下的开源框架,由Celtix + XFire这两门经典的框架合成,是一套非常流行的web service框架。
CXF的官方网站:
http://cxf.apache.org/download.html
它提供了对JAX-WS的全面支持,只需要拷入jar包即可,不需要任何改动,同时它能与spring进行完美结合。

实际的应用场景中,通常采用更为专业的Java EE应用服务器来发布Web服务。
CXF是流行的Web服务开发框架之一,代表着Celtix和Xfire项目的合并

我们导入所有的jar包需要排除:geronimo-servlet_3.0_spec-1.0.jar,javax.servlet-api-3.1.0.jar。这个在我们tomcat中已经有了,重复会导致冲突

我们首先在web.xml中配置

<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:springws.xml</param-value>
</context-param>
<listener>
<listener-class>
    org.springframework.web.context.ContextLoaderListener
</listener-class>
</listener>
<servlet>
<servlet-name>CXFServlet</servlet-name>
<servlet-class>
    org.apache.cxf.transport.servlet.CXFServlet
</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>CXFServlet</servlet-name>
<url-pattern>/services/*</url-pattern>
</servlet-mapping>

我们发布的时候还是可以和以前一样创建WebService接口,与WebService实体类。

然后就是配置我们的spring文件配置,你会发现多了写不是spring里面的头文件,这是WXF中提供的。

<beans
    xmlns="http://www.springframework.org/schema/beans"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xmlns:p="http://www.springframework.org/schema/p"
    xmlns:context="http://www.springframework.org/schema/context"
    xmlns:jaxws="http://cxf.apache.org/jaxws"
    xsi:schemaLocation="http://www.springframework.org/schema/beans         
      http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
      http://www.springframework.org/schema/context                 
      http://www.springframework.org/schema/context/spring-context-3.0.xsd
      http://cxf.apache.org/jaxws
      http://cxf.apache.org/schemas/jaxws.xsd
      http://cxf.apache.org/bindings/soap 
    http://cxf.apache.org/schemas/configuration/soap.xsd">
    
    <import resource="classpath:META-INF/cxf/cxf.xml"/>
    <!-- 在CXF3.0之后不需要下面这两个,不然会报错 -->
    <!-- <import resource="classpath:META-INF/cxf/cxf-extension-soap.xml"/>
    <import resource="classpath:META-INF/cxf/cxf-servlet.xml"/> -->
</beans>    

然后我们有两种方式配置

<!-- 第一种配置方式 -->
    <bean id="weatherService" class="com.webservice.server.WeatherServiceImpl" />
    <jaxws:endpoint id="wsServiceBean" implementor="#weatherService"
        address="/getWeather" publish="true" />

    <!-- 第二种配置方式 -->
    <jaxws:server serviceClass="com.webservice.server.WeatherServiceImpl"
        address="/getWeather" />

然后我们直接跑这个项目,我们不需要添加任何的页面,它自己会生成页面但是我们会报404的错误,因为在web配置中你直接访问项目会默认查询index.html,index.jsp等这也默认访问的页面。我们可以下连接下访问路径services,这个路径是我们在web.xml中配置的路径。访问:http://localhost:8080/SpringCXF/services,然后我们会看到如下页面:

在spring配置中address就是路径名,可以在图片上清晰看到。publish是决定是否发布。我们可以去调用WSDL接口

使用CXF调用服务

在CXF中也给我们提供了一种生成方式在我们官方下载的CXF解压出来有个bin目录

 我们需要为它配置环境变量然后调用wsdl2java来生成使用起来都是差不多的。

JaxWsProxyFactoryBean bean = new JaxWsProxyFactoryBean();
bean.setServiceClass(WeatherService.class);
bean.setAddress("http://localhost:8080/SpringCxfServer/services/getWeather?wsdl");
WeatherService service = (WeatherService) bean.create();
System.out.println(service.getProvince());

基于json的web服务:

早期webservice是基于xml格式的,具有良好的跨平台性和跨语言性。但是由于这几年json格式的兴起,json是同样也具备跨语言和跨平台性,并且格式更加简洁。所以这几年基于json格式的web服务也越来越流行。
基于json的服务提供商。
百度 appstore
聚合数据

这些很多都是收费的,不过使用起来并不难,提供里面会有调用方式。

猜你喜欢

转载自www.cnblogs.com/SimpleWu/p/9687834.html