zoukankan      html  css  js  c++  java
  • WebService使用介绍(三)

    jax-ws开发深入

    JAX-WS注解

    注解说明

    WebService的注解都位于javax.jws包下:

    @WebService-定义服务,在public class上边

    targetNamespace:指定命名空间

    nameportType的名称

    portNameport的名称

    serviceName:服务名称

    @WebMethod-定义方法,在公开方法上边

    operationName:方法名

    exclude:设置为true表示此方法不是webservice方法,反之则表示webservice方法

    @WebResult-定义返回值,在方法返回值前边

    name:返回结果值的名称

    @WebParam-定义参数,在方法参数前边

    name:指定参数的名称

    作用:

    通过注解,可以更加形像的描述Web服务。对自动生成的wsdl文档进行修改,为使用者提供一个更加清晰的wsdl文档。

    当修改了WebService注解之后,会影响客户端生成的代码。调用的方法名和参数名也发生了变化

    注解示例:

    /**
     * 天气查询服务接口实现类
     * @author SMN
     * @version V1.0
     */
    @WebService(targetNamespace="http:// webservice.itcast.cn",
    serviceName="weatherService",
    portName="weatherServicePort",
    name="weatherServiceInterface"
    )
    public class WeatherInterfaceImpl implements WeatherInterface {
        
        @WebMethod(operationName="queryWeather")
        public @WebResult(name="weatherResult")String queryWeather(
                @WebParam(name="cityName")String cityName) {
            System.out.println("from client.."+cityName);
            String result = "晴朗";
            System.out.println("to client..."+result);
            return result;
        }
        
        public static void main(String[] args) {
            //发送webservice服务
            Endpoint.publish("http://192.168.1.100:1234/weather", new WeatherInterfaceImpl());
        }
        
    }

    使用注解注意

    @WebMethod对所有非静态的公共方法对外暴露为服务.

    对于静态方法或非public方法是不可以使用@WebMethod注解的.

    public方法可以使用@WebMethod(exclude=true)定义为非对外暴露的服务。

    jax-ws发布为web工程

    webservice发布在web工程可以使用webservice接口和web应用的其它链接共存。

    Jax-ws开发的webservice 发布至web容器需要使用jax-wsRI(扩展实现), https://jax-ws.java.net/下载jax-wsRI最新版本,本次使用jaxws-ri-2.2.8版本。

    第一步:下载jaxws-ri-2.2.8的扩展包

    第二步:创建web工程

    第三步:将扩展包中的jar拷贝至web工程下

    第四步:编写服务端代码,编写方法与之前我们学习的jax-ws方法一致

    如果需要生成soap1.2@WebServer下添加:

    @BindingType(value="http://www.w3.org/2003/05/soap/bindings/HTTP/")

    package cn.itcast.weather.server;
    import java.text.SimpleDateFormat;
    import java.util.ArrayList;
    import java.util.Calendar;
    import java.util.Date;
    import java.util.List;
    import javax.jws.WebService;
    import javax.xml.ws.BindingType;
    import javax.xml.ws.Endpoint;
    /**
     * 使用jax-ws开发webservice
     * 数据类型采用自定义对象类型,list等
     *
     */
    @WebService(name="WeatherServer",serviceName="WeatherServerService",portName="WeatherServerPort")
    public class ServerJws {
    /**
     * 通过城市查询天气信息,返回未来两天的天气信息
     */
    public List<WeatherModule> queryWeatherByCity(String city){
    System.out.println("正在查询"+city+"的天气...");
    //未来三天的天气信息
    List<WeatherModule> weathers = new ArrayList<WeatherModule>();
    //今天的天气
    WeatherModule weatherModule1 = new WeatherModule();
    //城市
    weatherModule1.setCityName(city);
    //日期
    Date date1 = new Date();
    SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyy年MM月dd日");
    String datesString1 = simpleDateFormat.format(date1);
    weatherModule1.setDate(datesString1);
    //天气
    weatherModule1.setWeather("晴");
    //温度
    weatherModule1.setTemperature("最高温度11度,最低温度1度");
    weathers.add(weatherModule1);
    //明天的天气
    WeatherModule weatherModule2 = new WeatherModule();
    //城市
    weatherModule2.setCityName(city);
    //日期
    //创建日历对象
    Calendar calendar = Calendar.getInstance();
    int day = calendar.get(Calendar.DATE);
    //明天的日期
    calendar.set(Calendar.DATE, day+1);
    Date date2 = calendar.getTime();
    String datesString2 = simpleDateFormat.format(date2);
    weatherModule2.setDate(datesString2);
    //天气
    weatherModule2.setWeather("阴");
    //温度
    weatherModule2.setTemperature("最高温度10度,最低温度-1度");
    weathers.add(weatherModule2);
    return weathers;
    } 
    public static void main(String[] args) {
    }
    }

    第五步:使用wsgen生成wsdl

    WEB-INF下创建wsdl目录,此目录存放生成的wsdl文件。

    1Cmd进入命令行

    2cd 工程目录

    3、执行wsgen

    格式为:

    wsgn [–wsdl] –cp <服务接口或类> [-r]

    -cp classpath(注意都是相对与当前目录)

    -r wsdl路径(注意都是相对与当前目录) 

    注意:如果要发布soap1.2协议,必须这里使用方法-wsdl:Xsoap1.2生成wsdl

    另外,服务类添加

    @BindingType(value="http://www.w3.org/2003/05/soap/bindings/HTTP/")

    Soap1.1方式

    wsgen -wsdl:soap1.1  -cp WebRootWEB-INFclasses cn.itcast.weather.server.ServerJws -r WebRootWEB-INFwsdl

    soap1.2方式

    wsgen -wsdl:Xsoap1.2 -extension -cp WebRootWEB-INFclasses cn.itcast.weather.server.ServerJws -r WebRootWEB-INFwsdl

    第六步:在web工程的WEB-INF下创建sun-jaxws.xml文件

    如果生成soap1.1内容下:

    <?xml version="1.0" encoding="UTF-8"?>
    <endpoints xmlns='http://java.sun.com/xml/ns/jax-ws/ri/runtime'
        version='2.0'>
        <endpoint name='ServerJws' implementation='cn.itcast.weather.server.ServerJws'
            wsdl='WEB-INF/wsdl/WeatherServerService.wsdl'
            url-pattern='/ webservice /weather' />
    </endpoints>

    url-pattern:为webservice服务地址

    如果生成soap1.2的方式:

    <?xml version="1.0" encoding="UTF-8"?>
    <endpoints xmlns='http://java.sun.com/xml/ns/jax-ws/ri/runtime'
            version='2.0'>
        <endpoint name='WeatherServer'
                implementation='cn.itcast.ws.server.WeatherServer'
                wsdl='WEB-INF/wsdl/WeatherServerService.wsdl'
                binding="http://www.w3.org/2003/05/soap/bindings/HTTP/" 
                url-pattern='/ webservice /weather '/>
    </endpoints>

    url-pattern:为webservice服务地址

    第七步:在web工程的web.xml中添加监听及servlet

    <listener>
            <listener-class>com.sun.xml.ws.transport.http.servlet.WSServletContextListener</listener-class>
    </listener>  
    <servlet>
            <servlet-name> webservice </servlet-name>
            <servlet-class>com.sun.xml.ws.transport.http.servlet.WSServlet</servlet-class>
            <load-on-startup>1</load-on-startup>
    </servlet>
    <servlet-mapping>
            <servlet-name> webservice </servlet-name>
            <url-pattern>/webservice/*</url-pattern>
    </servlet-mapping>

    Web.xml/ webservice /必须和sun-jaxws.xml中的url-pattern="/ webservice / "相匹配。

    通常将<url-pattern>定义为/ws/*,以/ws/匹配url,匹配到了则按webservice解析, sun-jaxws.xmlurl-pattern也必须配置成/ws/XXXX 

    第八步:启动tomcat

    访问tomcat下的web工程即可(http://ip:端口/工程目录/webservice/weather)

    注意:web.xmlservlet解析的路径要和sun-jaxws.xml中的一致

    什么是CXF

    Apache CXF = Celtix + Xfire开始叫 Apache CeltiXfire,后来更名为 Apache CXF 了,以下简称为 CXFApache CXF 是一个开源的 web Services 框架,CXF 帮助您构建和开发 web Services 支持多种协议,比如:SOAP1.1,1,2XML/HTTPRESTful HTTP 或者 CORBA

    CORBACommon Object Request Broker Architecture公共对象请求代理体系结构,早期语言使用的WSC,c++,C#

    Cxf是基于SOA总线结构,依靠spring完成模块的集成,最终SOA方式。

    灵活的部署:可以运行有Tomcat,Jboss,Jetty(内置),weblogic上面。

    CXF的安装及配置

    从官网下载2.7.11

    环境变量配置:

    JAVA_HOME,

    CXF_HOME=cxf的目录

    Path = %JAVA_HOME%in;%CXF_HOME%in;

    CLASSPATH=.;%CXF_HOME%libcxf-manifest.jar 

    CXF例子

    第一步:创建java工程

    第二步:将cxfjar 包加入工程

    第三步:创建服务接口和服务实现类

    创建服务接口和服务类的方法同上边章节描述,编写SEISEI的实现。

    注意:与jaxws编程不同的是将@WebService注解加在接口上边。

    服务接口:

    使用cxf开发webservice这里只需要在接口上加@webservice注解即可,和jaxws开发不同。

    @WebService(targetNamespace="http://service.itcast.cn/",
    name="WeatherInterface",//porttype的名称
    portName="WeatherInterfacePort",
    serviceName="WeatherInterfaceService"
    )
    @BindingType(javax.xml.ws.soap.SOAPBinding.SOAP12HTTP_BINDING)
    public interface WeatherInterface {
        //根据城市名称查询未来三天的天气
        public List<WeatherModel> queryWeather(String cityName) throws Exception;
    }

    服务接口实现类:

    使用cxf开发不用在接口实现类上加@webservice注解,因为cxf发布服务时可以指定接口。

    public class WeatherInterfaceImpl implements WeatherInterface {
        
        @Override
        public List<WeatherModel> queryWeather(String cityName) throws Exception {
    
            //构造三天的天气结果
            Calendar calendar = Calendar.getInstance();
            int day = calendar.get(Calendar.DATE);
            
            WeatherModel weatherModel_1 = new WeatherModel();
            weatherModel_1.setDate(new Date());
            weatherModel_1.setDetail("晴朗");
            weatherModel_1.setTemperature_max(30);
            weatherModel_1.setTemperature_min(23);
            
            WeatherModel weatherModel_2 = new WeatherModel();
            calendar.set(Calendar.DATE, day+1);
            weatherModel_2.setDate(calendar.getTime());
            weatherModel_2.setDetail("晴转多云");
            weatherModel_2.setTemperature_max(28);
            weatherModel_2.setTemperature_min(21);
            
            WeatherModel weatherModel_3 = new WeatherModel();
            calendar.set(Calendar.DATE, day+2);
            weatherModel_3.setDate(calendar.getTime());
            weatherModel_3.setDetail("多云转小雨");
            weatherModel_3.setTemperature_max(25);
            weatherModel_3.setTemperature_min(18);
    
            List<WeatherModel> list = new ArrayList<WeatherModel>();
            list.add(weatherModel_1);
            list.add(weatherModel_2);
            list.add(weatherModel_3);
                
            return list;
        }
    }

    发布服务类:

    package cn.itcast.ws.jaxws.server;
    
    import org.apache.cxf.jaxws.JaxWsServerFactoryBean;
    
    /**
     * CXF发布jaxws服务类
     * @author Thinkpad
     *
     */
    public class Server {
    
        /**
         * @param args
         */
        public static void main(String[] args) {
            //创建服务工厂bean
            JaxWsServerFactoryBean jaxWsServerFactoryBean = new JaxWsServerFactoryBean();
            //指定服务接口
            jaxWsServerFactoryBean.setServiceClass(WeatherServerInterface.class);
            //指定服务实现对象
            jaxWsServerFactoryBean.setServiceBean(new WeatherInterfaceImpl());
         //指定webservice的地址
            jaxWsServerFactoryBean.setAddress("http://192.168.1.100:1234/weather");
            //创建webservice服务
            jaxWsServerFactoryBean.create();
        }
    
    }

    第四步:根据wsdl地址生成客户端代码

    我们分别使用wsimportwsdl2java生成客户端代码,都可以正常使用。

    **wsdl2java可以生成soap1.1soap1.2

    wsdl2java生成客户代码

    先让我们了解一下cxfwsdl2java工具,它的功能就如同wsimport一样,可以生成一堆客户端调用的代码。

    在命令行执行:

    wsdl2java –d . http://192.168.1.100:1234/weather?wsdl

    注意:

    生成后WeatherService报错:

    原因是cxf需要JAX-WS API 2.2jdk6jax-ws2.1 版本,需要

    wsdl2java 使用“-frontend jaxws21“

    即如下:

    wsdl2java –d . –frontend jaxws21 http://localhost:1234/weather?wsdl

    第五步:编写客户端:

    方式1、使用javax.xml.ws.Service调用客户端

    package cn.itcast.ws.jaxws.client;
    
    import java.net.MalformedURLException;
    import java.net.URL;
    
    import javax.xml.namespace.QName;
    import javax.xml.ws.Service;
    
    import cn.itcast.ws.jaxws.server.WeatherServerInterface;
    
    public class Client3 {
        
        public static void main(String[] args) throws MalformedURLException {
            
            //创建URL,资源定位
            URL url = new URL("http://192.168.1.100:1234/weather?wsdl"); 
            //Qname,确定命名空间地址,和服务视图名称
            QName qName = new QName("http://service.itcast.cn/", "WeatherInterfaceService");
            //创建service
            Service service = Service.create(url, qName);
            //创建porttype(服务端点)
            WeatherInterface weatherInterface = service.getPort(WeatherInterface.class);
            
            //通过服务端点调用服务方法
             weatherServerInterface.queryWather("郑州");
        }
        
    }

    方式2JaxwsProxyFactoryBean调用服务端:

         //创建代码工厂bean
            JaxWsProxyFactoryBean jaxWsProxyFactoryBean = new JaxWsProxyFactoryBean();
            //设置接口类型(portType)        jaxWsProxyFactoryBean.setServiceClass(WeatherInterface.class);
            //设置webservice地址        jaxWsProxyFactoryBean.setAddress("http://192.168.1.100:1234/weather");
            //创建portType调用实例
            WeatherInterface weatherInterface =(WeatherInterface) jaxWsProxyFactoryBean.create();
            //调用webservice
            weatherServerInterface.queryWather("郑州");

    SOAP1.2生成

    在服务接口和服务类的上面都添加

    @BindingType(javax.xml.ws.soap.SOAPBinding.SOAP12HTTP_BINDING)

    如下:

    @WebService

    @BindingType(javax.xml.ws.soap.SOAPBinding.SOAP12HTTP_BINDING)

    public interface WeatherServerInterface

    @WebService(endpointInterface = "cn.itcast.ws.jaxws.server.WeatherServerInterface")

    @BindingType(javax.xml.ws.soap.SOAPBinding.SOAP12HTTP_BINDING)

    public class WeatherServer implements WeatherServerInterface

    Cxfspring集成

    第一步:建立一个web项目

    第二步:填充CXF JAR包。

    第三步:创建服务接口及服务类

    服务接口:

    @WebService(targetNamespace="http://service.itcast.cn/",
    name="WeatherInterface",//porttype的名称
    portName="WeatherInterfacePort",
    serviceName="WeatherInterfaceService"
    )
    @BindingType(javax.xml.ws.soap.SOAPBinding.SOAP12HTTP_BINDING)
    public interface WeatherInterface {
        //根据城市名称查询公网天气服务接口
        public List<String> queryWeather(String cityName) throws Exception;
    }

    服务实现类: 

    需求:服务类需要调用公网天气查询客户端。

    public class WeatherInterfaceImpl implements WeatherInterface {
    
        //此为公网查询客户端需要通过spring配置并注入
       private WeatherWebServiceSoap weatherWebServiceSoap;
        
        @Override
        public List<String> queryWeather(String cityName) throws Exception {
            
            ArrayOfString arrayOfString = weatherWebServiceSoap.getWeatherbyCityName("郑州");
            List<String> results = arrayOfString.getString();
            for(String result:results){
                System.out.println(result);
            }
                        
            return results;
        }
    
        public WeatherWebServiceSoap getWeatherWebServiceSoap() {
            return weatherWebServiceSoap;
        }
    
        public void setWeatherWebServiceSoap(WeatherWebServiceSoap weatherWebServiceSoap) {
            this.weatherWebServiceSoap = weatherWebServiceSoap;
        }
    
    }

    公网天气查询代码生成

    将上边章节生成的公网天气查询客户端调用代码考入本工程。

    生成方法在此不再赘述。

    第四步:创建applicationContext.xml

    applicationContext.xml放在WEB-INF

    内容如下:

    <?xml version="1.0" encoding="UTF-8"?>
    <beans xmlns="http://www.springframework.org/schema/beans"
        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:jaxws="http://cxf.apache.org/jaxws"
        xmlns:jaxrs="http://cxf.apache.org/jaxrs" xmlns:cxf="http://cxf.apache.org/core"
        xsi:schemaLocation="http://www.springframework.org/schema/beans 
                                http://www.springframework.org/schema/beans/spring-beans.xsd
                                http://cxf.apache.org/jaxrs http://cxf.apache.org/schemas/jaxrs.xsd
                                http://cxf.apache.org/jaxws http://cxf.apache.org/schemas/jaxws.xsd
                                http://cxf.apache.org/core http://cxf.apache.org/schemas/core.xsd">
    <!-- 配置发布webservice服务 -->
    <jaxws:server address="/weather" serviceClass="cn.itcast.webservice.jaxws.server.WeatherInterface">
          <jaxws:serviceBean>
              <ref bean="weatherInterface"/>
          </jaxws:serviceBean>
    </jaxws:server>
    
    <!-- 公网天气查询客户端 -->
    <jaxws:client id="weatherClient" serviceClass="cn.com.webxml.WeatherWebServiceSoap" address="http://www.webxml.com.cn/WebServices/WeatherWebService.asmx" />
    
    
    <!-- 本系统对外服务的天气查询service -->
    <bean id="weatherInterface" class="cn.itcast.webservice.jaxws.server.WeatherInterfaceImpl" >
        <property name="weatherWebServiceSoap" ref="weatherClient" />
    </bean>
    
    </beans>

    第五步:在web.xml配置Spring环境

        <context-param>
           <param-name>contextConfigLocation</param-name>
           <param-value>/WEB-INF/applicationContext.xml</param-value>
        </context-param>
        <listener>
          <listener-class> org.springframework.web.context.ContextLoaderListener</listener-class>
        </listener>

    第六步:在web.xml配置CXFservlet

        <servlet>
            <servlet-name>cxf</servlet-name>
         <servlet-class>org.apache.cxf.transport.servlet.CXFServlet</servlet-class> <load-on-startup>1</load-on-startup> </servlet> <servlet-mapping> <servlet-name>cxf</servlet-name> <url-pattern>/ws/*</url-pattern> </servlet-mapping>

    第七步:启动web容器

    访问:http://192.168.1.100:8080/.../ws/weather?wsdl

    第八步:编写客户端工程

    客户端创建同前边章节,此处不再赘述。

  • 相关阅读:
    table的边框样式(小技巧)
    当人有更高目标追求的话,会发现周围的利益之争很可笑
    科普连载(原著:幽灵蝶)
    关于ASP.NET中的负载均衡
    验证控件与Button的OnClientClick事件(转)
    SQL Server 索引基础知识(2)聚集索引,非聚集索引(转)
    js中的Number和parseInt(小技巧)
    google的一些域名
    对多维宇宙的理解(时间、空间、超越光速,空间时间旅行)
    SNS
  • 原文地址:https://www.cnblogs.com/lm970585581/p/7771903.html
Copyright © 2011-2022 走看看