使用JDK发布和调用webservice服务

1、使用JDK发布webservice服务

  • 创建接口
package com.test.service;

public interface WeatherService {

    /**
     * 查询指定城市的天气
     * @param cityName 城市名称
     * @return
     */
    String queryWeather(String cityName);
}
  • 创建接口实现类,添加webservice服务端注解
package com.test.service.impl;

import com.test.service.WeatherService;
import javax.jws.WebService;

@WebService
public class WeatherServiceImpl implements WeatherService {

    @Override
    public String queryWeather(String cityName) {
        System.out.println("查询天气的城市为:" + cityName);
        String result = "该城市的天气为:晴天";
        System.out.println(result);
        return result;
    }

}
  • 发布webservice服务
package com.test.service;


import com.test.service.impl.WeatherServiceImpl;
import javax.xml.ws.Endpoint;

/**
 * 使用JDK的方式发布服务
 */
public class PushWebService {

    public static void main(String[] args) {
        //使用jdk提供的Endpoint类可以将webservice服务发布出去
        /**
         * Endpoint.publish(String address, Object implementor):
         * 参数1:提供服务对外的访问地址
         * 参数2:提供服务的类的对象
         */
        //发布查询天气的接口
        Endpoint.publish("http://localhost:8080/WeatherService",new WeatherServiceImpl());
        System.out.println("webservice接口发布成功");
    }

}

  • wsdl阅读的顺序是从下往上去阅读的。wsdl标签解释如下:
<service>服务视图,WebService的服务端点
<binding>Web Service的通信协议,其中描述额Web Service的方法、输入和输出
<protType>描述了Web Service可执行的操作,通过binding指向portType
<message>描述了服务中发布的方法,包括参数,返回值等
<types>定义了WebService总使用的数据类型
  • JDK中webservice相关注解部分属性值介绍
注解名作用范围属性作用
WebService作用在实现类上endpointInterfase当实现类实现了多个接口,但是我们又不想将一些接口中的方法发布出去时,就可以用该属性去选择需要发布出去的接口,属性值为接口的全路径
WebMethod作用在方法上exclud是否发布该方法,false表示不发布,默认为true
WebParam作用在方法的请求参数上name请求参数的名称,为了方便别人查看wsdl时能明白这个参数表明的意思
WebResult作用在方法的返回值上name返回参数的名称,为了方便别人查看wsdl时能明白这个参数表明的意思
  • 注意事项
1、Endpoint是java jdk提供的类,用来发布webservice,所以你的jdk版本必须在1.6.0_21之上....

2、被发布的类当中必须包含一个有效(方法必须为public的非静态,非final的方法)的方法

3、被发布的类上面必须有"@WebService"注解,否则会抛出"Exception in thread "main" java.lang.IllegalArgumentException: class com.test.service.impl.WeatherServiceImpl has neither @WebService nor @WebServiceProvider annotation"错误

2、使用JDK调用webservice服务

  • 使用jdk自带的wsimport命令根据服务端说明文档(wsdl)生成本地的java代码。wsimport命令介绍
  • 打开CMD窗口,输入“wsimport -encoding utf-8 -s D:\IdeaProjects\WebService\FirstWebService_Client\src -p com.test.service.impl http://localhost:8080/WeatherService?wsdl”命令生成服务端接口的java代码,结果如下所示:

  • 使用JDK的两种方式调用webservice接口
import com.test.service.impl.WeatherServiceImpl;
import com.test.service.impl.WeatherServiceImplService;
import org.junit.Test;
import javax.xml.namespace.QName;
import javax.xml.ws.Service;
import java.net.MalformedURLException;
import java.net.URL;

/**
 * 使用JDK的方式调用WebService服务
 */
public class UseWebService {

    @Test
    public void test1() {
        //该类名对应wsdl说明文档中的service标签中的name属性值
        WeatherServiceImplService service = new WeatherServiceImplService();
        //该类名对应wsdl说明文档中的portType标签中的name属性值。找到需要调用方法所在哪个portType标签中,然后去对应的name属性值即可
        WeatherServiceImpl weatherService = service.getPort(WeatherServiceImpl.class);
        String result = weatherService.queryWeather("郑州");
        System.out.println(result);
    }

    @Test
    public void test2() throws MalformedURLException {
        //wsdl文档地址
        URL url = new URL("http://localhost:8080/WeatherService?wsdl");
        /**
         * QName(String namespaceURI, String localPart)
         * 参数1:命名空间。对应wsdl说明文档中的definitions标签中的targetNamespace属性值
         * 参数2:服务名称。对应wsdl说明文档中的service标签中的name属性值
         */
        QName qName = new QName("http://impl.service.test.com/","WeatherServiceImplService");
        Service service = Service.create(url,qName);
        //获取接口类型
        WeatherServiceImpl weatherService = service.getPort(WeatherServiceImpl.class);
        //调用方法
        String result = weatherService.queryWeather("郑州");
        System.out.println(result);
    }

}