WebService(注解),CXF框架(jax-ws,Jax-rs,与spring整合)

前端之家收集整理的这篇文章主要介绍了WebService(注解),CXF框架(jax-ws,Jax-rs,与spring整合)前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。

转载:http://blog.csdn.net/opopopwqwqwq/article/details/51763570

1     webservice的注解


1.1   案例:

模拟查询天气信息,返回三天的天气情况。

 

1.1.1       实现步骤

服务端:

第一步:创建一个天气信息pojo,包含天气的信息、最高、最低温度、日期。

第二步:编写SEI

第三步:编写SEI实现类,返回天气list

第四步:发布Webservice。

 

1.1.2       代码实现

1.1.2.1    Pojo

[java]  view plain  copy
  1. public class WeatherModel {  
  2.   
  3.     private String info;  
  4.     private int maxTemp;  
  5. int minTemp;  
  6. private Date date;  

1.1.2.2    SEI

天气查询SEI,返回三天的天气情况

copy

    @WebService  
  1. interface WeatherInterface {  
  2.   
  3.     List<WeatherModel> queryWeather(String cityName);  
  4. }  


1.1.2.3    SEI实现类

实现类使用@WebService实现wsdl文档元素名称修改

copy

    @WebService(  
  1.         //endpointInterface="com.itheima.weather.service.WeatherInterface" //可以指定SEI接口  
  2.         name="WeatherInterface"//不使用SEI接口时规范portType的名称  
  3.         serviceName="WeatherService",   //服务视图的名称  
  4.         portName="WeatherPort",         //Service节点中port节点的name属性  
  5.         targetNamespace="http://weather.itheima.com/"   //wsdl的命名空间  
  6. )  
  7. class WeatherInterfaceImpl implements WeatherInterface {  
  8.     @Override  
  9.     @WebMethod/*(exclude=true)*/  
  10. @WebResult(name="WeatherInfo")  
  11. public List<WeatherModel> queryWeather(@WebParam(name="cityName")String cityName) {  
  12.         System.out.println("客户端发送的城市:" + cityName);  
  13.         //查询天气信息  
  14.         List<WeatherModel> info = getWeatherInfo(cityName);  
  15. //返回天气信息  
  16.         return info;  
  17.     }  
  18.       
  19. private List<WeatherModel> getWeatherInfo(String cityName) {  
  20.         List<WeatherModel> weatherList = new ArrayList<>();  
  21.         Calendar calendar = Calendar.getInstance();  
  22. //第一天  
  23.         WeatherModel model1 = new WeatherModel();  
  24.         model1.setInfo("雷阵雨");  
  25.         model1.setMaxTemp(31);  
  26.         model1.setMinTemp(22);  
  27.         model1.setDate(calendar.getTime());  
  28.         weatherList.add(model1);  
  29. //第二天  
  30.         WeatherModel model2 = new WeatherModel();  
  31.         model2.setInfo("多云");  
  32.         model2.setMaxTemp(33);  
  33.         model2.setMinTemp(25);  
  34.         calendar.set(Calendar.DATE, calendar.get(Calendar.DATE) + 1);  
  35.         model2.setDate(calendar.getTime());  
  36.         weatherList.add(model2);  
  37. //第三天  
  38.         WeatherModel model3 =          model3.setInfo("多云");  
  39.         model3.setMaxTemp(35);  
  40.         model3.setMinTemp(         model3.setDate(calendar.getTime());  
  41.         weatherList.add(model3);  
  42.           
  43. return weatherList;  
  44. 1.1.2.4    客户端

    copy

    class WeatherClient {  
  1. static void main(String[] args) throws Exception {  
  2. //创建服务视图  
  3.         Service service = Service.create(new URL("http://127.0.0.1:12345/weather"),   
  4.                 new QName("http://service.weather.itheima.com/""WeatherInterfaceImplService"));  
  5. //从服务视图获得protType对象  
  6.         WeatherInterfaceImpl weatherInterfaceImpl = service.getPort(WeatherInterfaceImpl.class);  
  7. //调用服务端方法  
  8.         List<WeatherModel> list = weatherInterfaceImpl.queryWeather("北京");  
  9. //显示天气信息  
  10. for (WeatherModel weatherModel : list) {  
  11.             System.out.println(weatherModel.getDate().toGregorianCalendar().getTime().toLocaleString());  
  12.             System.out.println(weatherModel.getInfo());  
  13.             System.out.println(weatherModel.getMaxTemp());  
  14.             System.out.println(weatherModel.getMinTemp());  
  15.               
  16.         }  
  17. }  

1.2   要规范wsdl需要使用到webservice注解


1.2.1       @Webservice

@WebService(

              //endpointInterface="com.itheima.weather.service.WeatherInterface"//可以指定SEI接口

              name="WeatherInterface",//不使用SEI接口时规范portType的名称

              serviceName="WeatherService",   //服务视图的名称

              portName="WeatherPort",                   //Service节点中port节点的name属性

              targetNamespace="http://weather.itheima.com/"   //wsdl的命名空间

                     )

1.2.2       @WebMethod

如果不指定@WebMethod注解默认是吧实现类中所有的public方法都发布成服务方法

如果类中有的public方法不想发布成服务,就可以使用@WebMethod(exclude=true)把此方法排除,也就是不发布为webservice方法

注意:每个Porttype中,必须有一个public方法并且不能标注为@WebMethod(exclude=true)

1.2.3       @WebParam、@WebResult

可以规范参数的名称

@WebResult(name="xxxx")修改返回值的元素的父标签名字

@WebParam(name="xxxxx")修改传入参数的元素的父标签名字

 

2     CXF框架

2.1   什么是CXF

Apache CXF = Celtix + Xfire,开始叫 Apache CeltiXfire,后来更名为 Apache CXF 了,以下简称为 CXF。Apache CXF 

是一个开源的 web Services 框架,CXF 帮助您构建和开发 web Services ,它支持多种协议,比如:SOAP1.1,1,2、XML/HTTP、RESTful  或者 CORBA。

RESTful:一种风格而不是一个协议。它理念是网络上的所有事物都被抽象为资源,每个资源对应一个唯一的资源标识符。

CORBA(Common Object Request Broker Architecture公共对象请求代理体系结构,早期语言使用的WS。C,c++,C#)

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

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

2.2   CXF的安装及配置

从官网下载:cxf.apache.org

学习使用的版本是:3.0.2

使用的方法,直接把cxf的jar包添加到工程中就可以了。

环境配置

JAVA_HOME 需要jdk的支持

CXF_HOME  解压目录(bin的上层目录) 需要使用bin目录的可执行命令生成客户端代码

 

path = %JAVA_HOME%\bin;%CXF_HOME%\bin;

 

2.3   使用CXF实现java-ws规范的webservice

Soap1.1:

2.3.1       服务端

实现步骤:

第一步:创建一Java工程。

第二步:导入jar包导入cxf的jar包共138个。

第三步:编写SEI,在SEI上添加@Webservice注解。

第三步:编写SEI实现类。需要实现SEI接口,可以不加@Webservice注解

第四步:发布服务。

1、创建一个JaxWsServerfactorybean对象。

2、设置服务的发布地址,是一个http url

3、设置SEI接口

4、设置SEI实现类对象

5、调用create方法发布服务。

2.3.2       代码实现

2.3.2.1    SEI

copy

        String queryWeather(String cityName);  
  1. 2.3.2.2    实现类

    copy

      implements WeatherInterface {  
    1. @Override  
    2. public String queryWeather(String cityName) {  
    3.         System.out.println("城市名称:" + cityName);  
    4.         String result = "多云";  
    5.           
    6.         return result;  
    7.     }  
    8. 2.3.3       发布服务

      服务发布类:后面整合spring按照此步骤配置即可

      copy

        class WeatherServer {  
      1. void main(String[] args) {  
      2. //创建一个JaxWsServerfactorybean对象  
      3.         JaxWsServerfactorybean factorybean = new JaxWsServerfactorybean();  
      4. //设置服务发布的地址  
      5.         factorybean.setAddress("http://127.0.0.1:12345/weather");  
      6. //设置SEI  
      7.         factorybean.setServiceClass(WeatherInterface.class);  
      8. //设置实现类对象  
      9.         factorybean.setServiceBean(new WeatherInterfaceImpl());  
      10. //发布服务  
      11.         factorybean.create();  
      12. 2.4   客户端

        2.4.1       Wsdl2java

        可以使用wsimport生成客户端调用代码,也可以使用CXF自带的工具生成。Wsdl2java。

        可以实现wsimport同样的功能,两个工具生成代码都是一样,wsdl2java工具的版本高。Wsimport对soap1.2支持的不好。

        它包含以下参数:

        a) -d参数,指定代码生成的目录。

        b) -p参数,指定生成的新的包结构。

        例:

        在命令行执行

        wsdl2java –d . -p cn.test.cxftext http://127.0.0.1:6666/helloworld?wsdl

        2.4.2       客户端的代码实现

        2.4.2.1    实现步骤

        1、可以直接使用生成代码调用服务端方法

        2、使用CXF提供的工厂类调用

        第一步:创建JaxWsProxyfactorybean对象

        第二步:设置服务的url,服务端地址

        第三步:设置SEI(portType)类型

        第四步:调用Create方法获得portType对象。

        第五步:调用服务端方法

        2.4.2.2    代码实现

        使用CXF工厂调用webservice,后面与spring整合配置可以用来参考

        copy

          //创建一个JaxWsProxyfactorybean对象  
        1.         JaxWsProxyfactorybean factorybean = new JaxWsProxyfactorybean();  
        2. //设置服务的url  
        3.         factorybean.setAddress("http://127.0.0.1:12345/weather?wsdl");  
        4. //设置SEI的类型  
        5. //获得porttype对象  
        6.         WeatherInterface portType = (WeatherInterface) factorybean.create();  
        7. //调用服务端方法  
        8.         String result = portType.queryWeather("北京");  
        9.         System.out.println(result);  
        10. 2.5   Jax-rs规范的webservice

          2.5.1       什么是rest服务

          一句话解释:URL定位资源,用HTTP动词(GET,POST,DELETE,DETC)描述操作。

          简单来讲,就是可以用httprequest 调用某个function. 比如在浏览器里输入www.chx.site/api/guesswhoisawesome,就会调用后台的某个function得到一个response(可以是Json).

          REST 是一种软件架构风格,设计风格而不是标准,只是提供了一组设计原则和约束条件。

          它主要用于客户端和服务器交互类的软件。基于这个风格设计的软件可以更简洁,更有层次,更易于实现缓存等机制。

          rest服务采用HTTP 做传输协议,REST 对于HTTP 的利用分为以下两种:资源定位资源操作

          关于JAX-WS与JAX-RS:

          两者是不同风格的SOA(面向服务的体系结构)架构。

          前者以动词为中心,指定的是每次执行函数

          而后者以名词为中心,每次执行的时候指的是资源。

              资源定位

          Rest要求对资源定位更加准确,如下:

          非rest方式:http://ip:port/queryUser.action?userType=student&id=001

          Rest方式:http://ip:port/user/student/001

          Rest方式表示互联网上的资源更加准确,但是也有缺点,可能目录的层级较多不容易理解。

              资源操作

          利用HTTP 的GET、POST、PUT、DELETE 四种操作来表示数据库操作的SELECT、UPDATE、INSERT、DELETE 操作。

          比如:

          查询学生方法

          设置Http的请求方法为GET,url如下:

          http://ip:port/user/student/001

          添加学生方法

          设置http的请求方法为PUT,url如下:

          http://ip:port/user/student/001/张三/......

          Rest常用于资源定位,资源操作方式较少使用。

          REST 是一种软件架构理念,现在被移植到Web 服务上,那么在开发Web 服务上,

          偏于面向资源的服务适用于REST,REST 简单易用,效率高,

          SOAP 成熟度较高,安全性较好。

          注意:REST 不是WebService,JAX-RS 只是将REST 设计风格应用到Web 服务开发上。

          代码实现

          2.5.2       服务端

          2.5.2.1    实现步骤

          第一步:创建一个pojo,返回值的类型。需要在pojo上添加@XmlRootElement。

          第二步:创建一个SEI。也就是一个接口。需要用到的注解

          1、@Path:标注请求url

          2、@GET、@POST、@PUT、@DELETE:标注操作的方法

          3、@Produce:指定返回结果的数据类型,xml或者json等。

          第三步:创建SEI的实现类。可以不使用任何注解。

          第四步:发布rest服务。

          1、使用JAXRSServerfactorybean对象发服务。

          2、设置服务发布的地址。设置url

          3、设置SEI实现类对象。

          4、发布服务,create方法

          2.5.2.2    代码实现

          2.5.2.2.1 Pojo

          返回值pojo类需要添加一个@XmlRootElement注解

          copy

            @XmlRootElement  
          1. class WeatherModel {  
          2. private String info;  
          3. int maxTemp;  
          4. int minTemp;  
          5. private Date date;  

           

          2.5.2.2.2 SEI

          rest服务SEI

          copy

            //窄化请求映射  
          1. @Path("/weather")  
          2. interface WeatherInterface {  
          3.     //方法的请求路径{}中的内容就是参数,需要对应的使用@PathParam注解取参数  
          4. @Path("/city/{cityName}")  
          5. //请求的方法  
          6. @GET  
          7. //返回结果的数据类型,可以是xml也可以是json  
          8. @Produces({MediaType.APPLICATION_JSON+";charset=utf-8", MediaType.APPLICATION_XML})  
          9.     List<WeatherModel> queryWeather(@PathParam(value="cityName")String cityName);  
          10. 2.5.2.2.3 SEI实现类

            copy

              implements WeatherInterface{  
            1. public List<WeatherModel> queryWeather(String cityName) {  
            2.         List<WeatherModel> weatherInfo = getWeatherInfo(cityName);  
            3. return weatherInfo;  
            4. ...  

            2.5.2.2.4 发布服务

            使用执行命令生成相应的代码

            copy

              //创建一个JAXRSServerfactorybean对象  
            1.         JAXRSServerfactorybean factorybean = new JAXRSServerfactorybean();  
            2.         factorybean.setAddress("http://127.0.0.1:12345/rest");  
            3.         factorybean.create();         
            4. 2.5.3       查看结果

              http://127.0.0.1:12345/rest/weather/city/上海

               

              2.5.4       如果是多个参数可以使用

               

              2.5.5       结果数据格式

              2.5.5.1    Json

              @Produces({MediaType.APPLICATION_JSON+";charset=utf-8",MediaType.APPLICATION_XML})

              其中charset=utf-8 为了防止出现乱码

              2.5.6       同一个方法返回两种数据类型

              支持xml或者json数据格式

              MediaType.APPLICATION_JSON

              MediaType.APPLICATION_XML

              默认返回xml格式的数据

              如果想访问json格式的数据需要加参数:?_type=json

              http://127.0.0.1:12345/rest/weather/city/%E4%B8%8A%E6%B5%B7?_type=json

              2.5.7       客户端

              可以使用ajax请求json数据。还可以使用HttpClient访问数据。需要自己转换成java对象。

              3     CXF整合spring

              3.1   整合的思路

              Spring就是一个容器,服务端让spring容器实现服务的发布。客户端使用spring容器完成获得porttype的过程,直接从spring容器中获得一个porttype对象。

              3.2   案例需求

              服务端发布手机号查询服务供客户端调用,服务端配置调用公网手机号查询服务客户端,调用公网WebService查询手机号。

              3.3   分析

               

                

              3.4   实现步骤

              服务端:有两个身份,一个是调用公网webservice的客户端。一个是对外提供手机号查询服务的服务端。

              第一步:实现调用公网webservice的客户端

              1、根据公网webservice的wsdl生成客户端调用代码

              2、配置spring容器,完成创建服务视图获得porttype的过程。直接从spring容器中获得prottype对象。

              3、直接调用porttype对象的服务端方法查询手机号。

              第二步:对外发布服务,实现手机号查询

              1、编写一个SEI接口。需要在SEI上添加@Webservice注解。

              2、编写一个SEI实现类,调用公网webservice的porttype实现手机号查询

              3、发布服务,使用spring容器完成。

              3.5   开发环境的搭建

              第一步:创建一个Web工程

              第二步:导入jar包。需要spring的jar包和cxf的jar包

              3.6   代码实现

              3.6.1       服务端

              3.6.1.1    生成调用公网webservice的客户端调用代码 

              3.6.1.2    在spring容器中配置porttype

              applicationContext.xml

              [html]  view plain  copy
                cxf:bus>  
              1.        cxf:properties>  
              2.            entry key="org.apache.cxf.logging.FaultListener"             <!-- 这个类可以换成自己的,如果不换就使用cxf中实现过上述接口的类 -->              
              3.                bean class="org.apache.cxf.logging.NoOpFaultListener"/>  
              4.            entry            >  

              需要的xmlns和xsd
              copy
                xmlns:cxf="http://cxf.apache.org/core  
              1. http://cxf.apache.org/core  
              2. http://cxf.apache.org/schemas/core.xsd  



              3.6.1.3    SEI

              调用公网webservice查询手机号的SEI

              copy

                interface MobileInterface {  
              1.     Mobile queryMobile(String code);  
              2.       
              3. 3.6.1.4    SEI实现类

                手机号归属地查询服务

                copy

                  class MobileInterfaceImpl implements MobileInterface {  
                1.     //公网webservice的porttype配置注入  
                2. private MobileCodeWSSoap mobileCodeWSSoap;    
                3. void setMobileCodeWSSoap(MobileCodeWSSoap mobileCodeWSSoap) {  
                4. this.mobileCodeWSSoap = mobileCodeWSSoap;  
                5. public Mobile queryMobile(String code) {  
                6. //第一个参数:手机号  
                7. //第二个参数:免费用户是空串  
                8.         String info = mobileCodeWSSoap.getMobileCodeInfo(code, "");  
                9.         Mobile mobile = new Mobile();  
                10.         mobile.setAddress(info);  
                11.         mobile.setCode(code);  
                12. return mobile;  
                13. 3.6.1.5    发布服务

                  3.6.1.6    Web.xml

                  配置spring容器,配置cxf使用servlet。

                  web.xml

                  copy

                    web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"  
                  1.     xmlns="http://java.sun.com/xml/ns/javaee" xmlns:web="http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"  
                  2.     xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"  
                  3.     id="WebApp_ID" version="2.5"display-name>B06_spring_cxf<!-- 配置spring容器 -->  
                  4. <!--  
                  5.         使用spring来加载cxf的服务类,服务类的对象由spring来创建,服务类的对象存在springIoc的容器中 
                  6.      -->  
                  7. context-paramparam-name>contextConfigLocation         param-value>classpath:applicationContext.xmllistenerlistener-class>org.springframework.web.context.ContextLoaderListener<!-- cxf的配置 -->  
                  8. <!-- servlet负责发布服务类 -->  
                  9. servletservlet-name>cxfservlet-class>org.apache.cxf.transport.servlet.CXFServlet         <!--设置随着服务器启动而载servlet,不设置访问时才会加载显示数据慢 -->  
                  10. load-on-startup>1servlet-mappingurl-pattern>/ws/*web-app>  

                  applicationContext.xml发布自己的服务
                  copy
                        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:jaxws="http://cxf.apache.org/jaxws"  
                  1.     xmlns:jaxrs="http://cxf.apache.org/jaxrs" xmlns:cxf="http://cxf.apache.org/core"  
                  2.                             http://cxf.apache.org/jaxrs http://cxf.apache.org/schemas/jaxrs.xsd  
                  3.                             http://cxf.apache.org/jaxws http://cxf.apache.org/schemas/jaxws.xsd  
                  4.                             http://cxf.apache.org/core http://cxf.apache.org/schemas/core.xsd"<!-- 配置调用公网webservice的客户端 -->  
                  5. <!-- 相当于一个普通的bean,可以当做对象使用 -->  
                  6. jaxws:client id="mobileCodeWSSoap" address="http://webservice.webxml.com.cn/WebServices/MobileCodeWS.asmx"   
                  7.             serviceClass="cn.com.webxml.MobileCodeWSSoap"/>  
                  8. <!-- 把SEI的实现类配置到spring容器 -->  
                  9. <!-- 发布服务 -->  
                  10. <!-- address就是服务发布的地址,只是从一个目录开始 -->  
                  11. <!-- serviceClass是发布服务的sei -->  
                  12. jaxws:server address="/mobile" serviceClass="com.itheima.mobile.service.MobileInterface"jaxws:serviceBean             ref bean="mobileInterfaceImpl"jaxws:server<!-- rest服务的实现类 -->  
                  13. bean id="mobileRestImpl" class="com.itheima.mobile.rest.MobileRestImpl"<!-- 发布rest服务 -->  
                  14. jaxrs:server address="/rest"jaxrs:serviceBeans             ref bean="mobileRestImpl"jaxrs:server                             
                  15. 3.6.1.7    访问路径

                    http://localhost:8081/B06_spring_cxf/ws/mobile?wsdl

                     

                    3.6.2       客户端

                    步骤:

                    1、生成客户端调用代码

                    2、创建服务视图

                    3、获得porttype

                    4、调用服务端方法

                    3.7   Spring整合cxf发布rest服务

                    3.7.1       实现步骤

                    第一步:调用公网webservice查询手机号,需要公网webservice的porttype。

                    第二步:发布rest服务

                    1、先写一个pojo,需要加上@xmlrootElement注解。

                    2、编写一个SEI,需要添加@path、@GET、@Produces

                    3、编写一个SEI实现类,需要调用公网的webservice查询手机号。

                    4、发布服务,使用spring容器发布服务。

                    3.7.2       代码实现

                    3.7.2.1    SEI

                    rest风格的服务

                    copy

                      @Path("/mobile")  
                    1. interface MobileRest {  
                    2. @Path("/code/{code}")  
                    3.     Mobile queryMobile(@PathParam(value = "code")String code);  
                    4. 3.7.2.2    SEI实现类

                      copy

                        class MobileRestImpl implements MobileRest {  
                      1. //公网webservice的porttype  
                      2. private MobileCodeWSSoap mobileCodeWSSoap;  
                      3. void setMobileCodeWSSoap(MobileCodeWSSoap mobileCodeWSSoap) {  
                      4. this.mobileCodeWSSoap = mobileCodeWSSoap;  
                      5.     }   
                      6. public Mobile queryMobile(String code) {  
                      7.         String address = mobileCodeWSSoap.getMobileCodeInfo(code, "");  
                      8.         Mobile mobile = new Mobile();  
                      9.         mobile.setAddress(address);  
                      10.         mobile.setCode(code);  
                      11. 3.7.2.3    发布服务

                        copy

                          3.7.2.4    Url的构成


                          使用jQuery调用cxf(ws)

                            
                        1.                   +'<soapenv:Body>'  
                        2.                   +'<q0:sayHello>'  
                        3.                   +'   <arg0>sss</arg0>'  
                        4.                   +' </q0:sayHello>'  
                        5.                   +'</soapenv:Body>'  
                        6.                   +'</soapenv:Envelope>';  
                        7.                     
                        8.                 $.ajax({  
                        9.                     url:'http://localhost:8080/cxf-web-server/services/hello',  
                        10.                     type:'post',  
                        11.                     dataType:'xml',108); list-style-type:decimal-leading-zero; color:inherit; line-height:18px; margin:0px!important; padding:0px 3px 0px 10px!important; list-style-position:outside!important">                     contentType:'text/xml;charset=UTF-8',248); line-height:18px; margin:0px!important; padding:0px 3px 0px 10px!important; list-style-position:outside!important">                     data:data,  
                        12.                     success:function(responseText){  
                        13.                         alert($(responseText).find('return').text());  
                        14.                     },  
                        15.                     error:                         alert("error");  
                        16.                     }  
                        17.                 })  
                        18.         })  
                        19.     })  

                        猜你在找的WebService相关文章