webService框架CXF的简单使用

    最近本来已经将上一个项目交活,全身心投入了另外项目的前端的开发工作。可之前的项目经理通知我,之前的项目需要做一个webService的功能,于是稍微做了一下webService,可是忘了通知我现在的项目经理,所以现在的项目经理以为我在做现在项目的前端工作,结果搞得很不好。然而我还是有私心的,因为目前两个项目需要使用的技术是我没有接触过的,而我的一个臭毛病就是对想做的喜欢做的技术会有莫名的兴奋感,每天早上起来的时候想到自己今天要将一个自己不了解的技术应用于工作中,就会很兴奋,恨不得立刻开始工作。总之,作为一个技术总结,也还是废话多谢,将职场经验写下:一定要将自己的任务让现在的负责人知道,即便别人已经告诉你现在的负责人已经知道了,你还是要和他确认一下,否则就有可能你做的两面不讨好。

  废话不多说,本周的技术要点如下:

  一、webService原理

    webService的有关知识网上太多了,但是我没有看懂,webService有关的三个要素:SOAP、UDDI 、WSDL ,我只知道了WSDL的使用方法。我所理解的webService如下:

    首先,webService是为了解决什么问题呢?因为我们知道系统中前端可以使用REST接口对后台进行数据请求,但是这是程序内部的数据接口,不可能直接发布给外部让别人使用url请求的,系统都会对这些开发的接口进行拦截和身份校验。那么如果我们想在外界获取到某个系统的数据,就需要webService了。比如天气信息网站的天气信息等公开分享的信息,我们都可以使用webService技术来获取。

    接下来webService是什么原理呢?我们都知道使用java进行接口开发的时候,参数和返回的结果一般会使用到实体类,比如有这样的一个接口,是通过用户的名字获取数据,那么此时的controller的方法可能会是这样写:

@RequestMapping(value = {"/list","/checkList"})
  public ResponseResult getUser(User u){
        ResponseResult re = this.createResult(u);
        return re;
    }

    接口中参数User为用户的实体类,前台传过来的用户名传到后台会自动封装成User对象。后台接口查询到数据后,会将数据封装成ResponseResule对象,传递给前台。这样前台就可以根据传递过来的信息展现数据了。

    通常开发的数据接口是前台和后台进行交互,之所以前台可以很方便的和后台进行交互,是因为前台对于参数对象和结果对象是使用JSON进行转换了,任你后台是什么实体类,在我前台面前一律全是JSON对象。

    但是对于webService的话,并不是前台和后台进行交互,而是后台和后台进行交互。比如系统A的后台语言是java,系统B的后台语言也是java,那么当系统B使用接口对系统A发起请求的时候,也是需要将一个实体对象作为参数传递过去,将一个实体对象作为查询结果进行返回。但是系统B怎么可能知道系统A的这个接口的参数实体对象和结果实体对象的构成呢?而如何让系统B知道接口中这两个对象的构成就成为了webService的重点。

    那么webService是怎么实现将系统A的接口的构成告诉给系统B的呢?

    首先webService需要一个服务端和客户端,很显然,系统A就是服务端,系统B就是客户端了。另外这个服务端需要新开一个servlet,以专供进行服务接口的请求。此时系统A会通过webService的服务端发布一个接口,这个接口和程序开发的接口不同之处在于:

    1、这个接口可以在外部访问,如果这个接口可以对外部共享的话,那么任何人都可以对这个接口进行访问;

    2、接口的结尾都是?WSDL(好像还有别的可能是实现技术不同,可通过查询天气的服务接口查看http://www.webxml.com.cn/zh_cn/weather_icon.aspx

    3、返回的是正常人看不懂的XML文档。

    这些东西光说是没用的,直接挂上天气服务的WSDL服务接口的url路径:http://www.webxml.com.cn/WebServices/WeatherWS.asmx?wsdl

    这样系统B在对服务接口进行请求后会获得一个xml文档,这个文档包含了想要请求到数据的前期一切信息。我们可以通过这个文档构建系统A的接口环境,重建参数对象和结果对象,构成一个客户端。这样当我们在对系统A进行数据请求的时候(此时的数据接口不是前面的获得wsdl的地址,可能放在xml文档中)就可以通过对象进行数据传输了。

    那么问题来了,怎么通过wsdl的这个xml文档重建接口环境,生成一个webService的客户端呢?

    其实这个方法有很多种,可以网上去查,我使用的方法是使用编辑器的内置的方法,idea和eclipse应该都有(后面的CXF的具体实现会有体现)。另外jdk的bin中也有一个wsimport.exe,可以进行转换具体使用方法为:wsimport -keep -p 自定义包名 -d 存放的地址 (wsdl地址)。不过我没有试过。。。。

  二、使用CXF框架构建webService

    CXF是webService的一个框架,可以很简单方便的搭建一个webService。现在我们做一个demo,具体过程如下:

    1、下载CXF http://cxf.apache.org/

    

          

    2、创建项目,将cxf的lib中的所有jar包引入到项目中

    3、创建服务端  

       我所生成的项目结构如下:

                

        其中,HelloWord是个接口,HellowWorldImp是其实现类,Servier用来创建一个服务,User是一个实体类,作为一个结构的参数对象。因此前三个是我们构成webServie服务端所必须的文件。先将三个文件的代码贴下:

        HelloWorld.java

package com;

import javax.jws.WebService;
import java.util.List;

/**
 * @InterfaceName HelloWorld
 * @Description TODO
 * @Author jyy
 * @Date 2019/7/18 10:45
 * @Version 1.0
 **/
@WebService
public interface HelloWorld {
     String sayHi(String text);
     String getUser(User user);
     List<User> getListUser();
}

        重要的是加上@WebService注解。接口里面的方法类似于controller中url对应的方法,可以理解为这个webService提供了三个接口服务:sayHi,getUser,getListUser。

        HelloWorldImpl.java

package com;

import javax.jws.WebService;
import java.util.ArrayList;
import java.util.List;

/**
 * @ClassName HelloWorldImp
 * @Description TODO
 * @Author jyy
 * @Date 2019/7/18 10:49
 * @Version 1.0
 **/
@WebService(endpointInterface = "com.HelloWorld", serviceName = "HelloWorldService",portName="HelloWorldServicePort")
public class HelloWorldImp implements HelloWorld {

    @Override
    public String sayHi(String text) {
        System.out.println("sayHi called...");
        return "Hi :" + text;
    }

    @Override
    public  String getUser(User user) {
        System.out.println("sayUser called...");
        return "User:[id=" + user.getId() + "][name=" + user.getName() + "]";
    }

    @Override
    public List<User> getListUser() {
        System.out.println("getListUser called...");
        List<User> lst = new ArrayList<User>();
        lst.add(new User(2, "u2"));
        lst.add(new User(3, "u3"));
        lst.add(new User(4, "u4"));
        lst.add(new User(5, "u5"));
        lst.add(new User(6, "u6"));
        return lst;
    }

}

        标红的注解是必须的,具体的值可自己配置

        Server.java

package com;

import javax.xml.ws.Endpoint;

public class Server {

    protected Server() throws Exception {
        // START SNIPPET: publish
        System.out.println("Starting Server");
        HelloWorldImp implementor = new HelloWorldImp();
        String address = "http://localhost:8080/helloWorld";
        Endpoint.publish(address, implementor);
        // END SNIPPET: publish
    }

    public static void main(String[] args) throws Exception {
        new Server();
        System.out.println("服务端已启动");
    }
}

        然后启动server.java中的main方法,启动一个服务器。然后在浏览器中输入网址:http://localhost:8080/helloWorld?wsdl,可以看到如下网页。

        

         此时,服务端搭建成功。

    4、创建客户端

      另开一个项目,用来模拟系统B

      然后构建客户端,我是用的idea,内置的构建方法截图如下:

      

      右键项目根目录,然后点击下面两个红箭头,出现如下截图:

      

      将wsdl的url地址填入第一个箭头所示,第二个为所创建的文件存放的文件夹,第三个是使用什么进行构建,其他的我都没有安装,使用的是如图的方法。完成后,idea会在demo目录先自动创建如下文件:

      

      记得eclipse可以通过wsdl的xml文档生成api,应该使用到了这些文件。

      假设知道了服务接口的api,那么就知道了怎么去请求了,接下来就需要构建客户端了。创建一个文件Main.java

      

package client;

import demo.HelloWorld;
import demo.HelloWorldService;

/**
 * @ClassName
 * @Description TODO
 * @Author jyy
 * @Date 2019/7/18 13:30
 * @Version 1.0
 **/
public class Main {
    public static void main(String[] args) {
        HelloWorldService factory = new HelloWorldService();

        // 此处返回的只是远程WebService的代理
        HelloWorld cxfWebService = factory.getHelloWorldServicePort();
        System.out.println(cxfWebService.sayHi("jyy"));
    }
}

      执行文件后,控制台显示:Hi :jyy

    至此,服务端和客户端搭建完成,webService流程演示完毕。

  三、将CXF集成到SpringMVC

    想要用于实际项目,就需要和项目中的框架集成,我是用的是SpingMVC。

    1、maven引入

<dependency>
            <groupId>org.apache.cxf</groupId>
            <artifactId>cxf-rt-frontend-jaxws</artifactId>
            <version>3.0.4</version>
</dependency>
<dependency>
            <groupId>org.apache.cxf</groupId>
            <artifactId>cxf-rt-transports-http</artifactId>
            <version>3.0.4</version>
</dependency>

      需要注意的是版本。我使用的springmvc版本是4,那么CXF需要是3。之前看别人的技术帖子CXF用的版本是2,所以一直报错。要是报错,如果代码没有问题的话,一定就是CXF的版本引入错了。切记切记

    2、配置文件中添加bean

<import resource="classpath:META-INF/cxf/cxf.xml" />
<import resource="classpath:META-INF/cxf/cxf-servlet.xml" />
<jaxws:endpoint id="helloService" implementor="com.zzdc.cxf.CXFWebServiceImpl"  address="/cxfService" />

      注意这里的使用的是项目实际中的文件,所以服务接口路径和文件和上一个demo中的是不同的。

    3、web.xml中创建一个servlet

<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>/cxf/*</url-pattern>
</servlet-mapping>

    启动后发布,此时url的地址应该是:localhost:8080/cxf/cxfService?wsdl,也就是由上面配置文件中bean的address和web.xml中的url-pattern所组成,需要注意。

第一周技术博客完成!

原文地址:https://www.cnblogs.com/jyybeam/p/11219642.html

时间: 2024-10-25 08:06:16

webService框架CXF的简单使用的相关文章

WebService框架CXF实战一在Tomcat中发布WebService(二)

服务接口及实现类请参考WebService框架CXF实战(一) 创建Maven Web项目,在pom.xml中添加CXF和Spring Web的引用,由于CXFServlet需要Spring Web的支持. <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation=&quo

WebService框架CXF实战(一)

Apache CXF提供了用于方便地构建和开发WebService的可靠基础架构.它允许创建高性能和可扩展的服务,可以部署在Tomcat和基于Spring的轻量级容器中,也可以部署在更高级的服务器上,例如Jboss.WebSphere或WebLogic. CXF提供了以下功能: WebService服务标准支持: Java API for XML Web Services (JAX-WS) SOAP WebService描述语言(Web Services Description Language

webservice框架cxf

由于cxf的web项目已经集成了Spring,所以cxf的服务类都是在spring的配置文件中完成的.以下是步骤: 第一步:建立一个web项目. 第二步:准备所有jar包.将cxf_home\lib项目下的所有jar包全部copy到新项目的lib目录下,里面已经包含了spring3.0的jar包. 第三步:在web.xml中配置cxf的核心servlet,CXFServlet. 第四步:创建(最好是Copy)cxf-servlet.xml文件.这是一个spring的配置文件. 1.web.xml

WebService框架CXF实战一RESTFul服务(七)

JAX-RS概述 JAX-RS是Java提供用于开发RESTful Web服务基于注解(annotation)的API.JAX-RS旨在定义一个统一的规范,使得Java程序员可以使用一套固定的接口来开发REST应用,避免了依赖第三方框架.同时JAX-RS使用POJO编程模型和基于注解的配置并集成JAXB,可以有效缩短REST应用的开发周期.JAX-RS只定义RESTful API,具体实现由第三方提供,如Jersey.Apache CXF等. JAX-RS包含近五十多个接口.注解和抽象类: ja

WebService框架CXF实战一发布RESTFul服务(七)

JAX-RS概述 JAX-RS是Java提供用于开发RESTful Web服务基于注解(annotation)的API.JAX-RS旨在定义一个统一的规范,使得Java程序员可以使用一套固定的接口来开发REST应用,避免了依赖第三方框架.同时JAX-RS使用POJO编程模型和基于注解的配置并集成JAXB,可以有效缩短REST应用的开发周期.JAX-RS只定义RESTful API,具体实现由第三方提供,如Jersey.Apache CXF等. JAX-RS包含近五十多个接口.注解和抽象类: ja

WebService框架CXF实战一传输文件(六)

CXF的文件传输通过MTOM实现.MTOM(SOAP Message Transmission Optimization Mechanism)SOAP消息传输优化机制,可以在SOAP消息中发送二进制数据.MTOM允许将消息中包含的大型数据元素外部化,并将其作为无任何特殊编码的二进制数据随消息一起传送.相对于把二进制转为base64进行传输,MTOM具有更高的传输效率. 文件传输包装类 CXF文件传输DataHandler只有二进制数据,没有文件名.文件类型和文件大小等,需要额外的传输参数.通常自

WebService框架CXF实战一自定义拦截器(五)

CXF已经内置了一些拦截器,这些拦截器大部分默认添加到拦截器链中,有些拦截器也可以手动添加,如手动添加CXF提供的日志拦截器.也可以自定义拦截器,CXF中实现自定义拦截器很简单,只要继承AbstractPhaseInterceptor或者AbstractPhaseInterceptor的子类(如AbstractSoapInterceptor)即可. 自定义权限认证拦截器 权限认证拦截器处理SOAPHeader中的认证信息,客户端在发起请求时在SOAPHeader中添加认证信息,服务端在接收到请求

WebService框架CXF实战一拦截器Interceptor(四)

拦截器(Interceptor)是CXF功能最主要的扩展点,可以在不对核心模块进行修改的情况下,动态添加很多功能.拦截器和JAX-WS Handler.Filter的功能类似,当服务被调用时,就会创建一个拦截器链(Interceptor Chain),拦截器链在服务输入(IN)或输出(OUT)阶段实现附加功能. 拦截器可以在客户端,也可以在服务端添加.当客户端发起一个WebService请求时,在客户端会创建输出拦截器链,服务端接收到客户端的后,会创建输入拦截器链.当服务端返回响应消息时,响应消

Webservice与CXF框架快速入门

1. Webservice Webservice是一套远程调用技术规范 远程调用RPC, 实现了系统与系统进程间的远程通信.java领域有很多可实现远程通讯的技术,如:RMI(Socket + 序列化).Binary-RPC(Http+二进制, 代表Hessian).XML-RPC(Http+XML, 代表Burlap, WebService用的SOAP).JMS(使用消息机制).Mina(使用NIO)等, 底层都是基于http/socket和网络IO来实现的.从效率上来讲, RMI > Hes