什么是CXF

Apache CXF = Celtix + Xfire
支持多种协议:
SOAP1.1,1.2
XML/HTTP
CORBA(Common Object Request Broker Architecture公共对象请求代理体系结构,早期语言使用的WS。C,c++,C#)

并可以与Spring进行快速无缝的整合
灵活的部署:可以运行在Tomcat,Jboss,Jetty(内置),IBMWS,BeaWL上面。

下载:

CXF的结构:

下载完成后将其解压到某个目录下:

安装CXF的其他支持项目

Ant
Tomcat
并设置以下环境变量:

JAVA_HOME
CXF_HOME
ANT_HOME
CATALINA_HOME
Path = %JAVA_HOME%\bin;%CXF_HOME%\bin;%CATALINA_HOME%\bin;%ANT_HOME%\bin
CLASSPATH=.;%CXF_HOME%\lib\cxf-manifest.jar;.\build\classes

用ANT来构造第一个CXF示例:

在cxf_home\samples\java_first_pojo目录下启动服务器:
在命令行模式下进入上述目录:
执行 以下命令 ant server
在同一目录下打开新命令行窗口运行:
ant client

查看它的源代码并修改运行:

用ANT将它发布到Tomcat服务器上:

1、执行ant clean清除以前生成的代码
2、执行ant war打包此应用。
3、执行ant deploy –Dtomcat=true将项目发布到tomcat的服务器上。
4、启动tomcat服务器
5、打开IE的地址栏输入:
http://localhost:9999/helloworld/services/hello_world?wsdl
或:http://localhost:9999/helloworld/services
6、在命令行执行:
ant client-servlet –Dbase.url=http://localhost:9999
或在MyEclipse的WebServiceExplorer中访问这个WebService
7、停止tomcat服务器。
8、卸载应用:ant undeploy –Dtomcat=true
9、清空项目:ant clean

在Eclipse中开发CXF的JavaSE应用:

导入CXF中的 所有jar文件。可以通过WACH_JARS来观察各jar文件的用途。

建立好之后的项目如
图所示:

CXF发布服务的类:

用两个不同的类发布应用:
ServerFactoryBean -- FacotryBean
JaxWsServerFactoryBean(建议使用此类)

服务与客户端类调用原则:

使用ServerFactoryBean发布服务:

使用ServerFactoryBean发布服务。
使用CXF发布一个服务,与JDK6发布一个服务完全不同
* 即使是不使用@WebService注解,一样可以发布成功
* 即使此类没有对外公布的方法一样可以发布成功

使用ClientProxyFactoryBean客户端调用:

使用ServerFactoryBean发布服务以后,在没有接口的情况下,可以使用wsimport生成的客户端代码调用成功。
但如果要使用ClientProxyFactoryBean客户端去调用服务器,则必须要先在服务器端创建一个接口。(一直以来,Spring都要求面向接口编程,而cxf与Spring能很好的整合,也就在此。),所以,必须要重写服务器端的代码。这将导致刚才使用wsimport生成的调用代码失效。
同时, ClientProxyFactoryBean由于要用到CXF环境,所以要导入CXF的所有包。
同时,如果是在本项目中调用,则可以直接使用本项目的接口。
如果在其他项目中调用,仍然需wsimport生成的类,但只需要一个接口。

使用JaxWsServerFactoryBean发布服务: (建议使用此类)

JaxWsServerFactoryBean是ServerFactoryBean的子类,也是功能扩展类。
但在CXF的API文档中没有提供此类API,请通过查看源代码的方式获取此类的帮助。
此类,必须要在被发布为服务的类上添加@WebService注解,如果不加注解,虽然不
出错,但也不会对外暴露任何方法。
使用此类生成的wsdl文件更加规范。
以下是从它的源代码中找到的对此类的说明。

使用CXF的类发布一个服务:

使用JaxWsProxyFactoryBean客户端调用

此调用过程与ClientProxyFactoryBean的要求一样,也必须要拥有一个接口。
此时,仍然可以使用wsimport生成接口,在其他项目的调用。

规范的做法应该是先书写一个接口,如下:

如果不是使用spring的配置文件发布,可以没有接口文件,但在任何情况下建议拥有接口文件。如果使用spring的配置文件发布,则必须要拥有接口类。

wsdl2java生成客户代码:

在cxf中,也提供了一个用于生成客户端调用代码的工具。它的功能就如同wsimport一样。
先让我们了解一下cxf的wsdl2java工具,可以生成一堆客户端调用的代码。
此工具位于cxf_home/bin目录下。参数与wsimport有所不同。
它包含以下参数:
-d参数,指定代码生成的目录。
-p参数,指定生成的新的包结构。
需要说明的是,由于wsdl2java是根据jdk1.7生成的本地代码,所以,需要对生成的代码做一点点修改。
在命令行执行:
wsdl2java –d . http://127.0.0.1:6666/helloworld?wsdl

调用端代码:

给服务添加消息拦截器:-这个非常有用:

LoggingInInterceptor – 信息输入时的拦截器 –请求
LoggingOutInterceptor –信息输出时的拦截器-响应

给服务器添加拦截器,类似于使用TCP/IP Monitor来捕获SOAP消息的过程。

使用JavaScript也可以访问WebServie:

jQuery访问WebService.
1、在本域准备jquery.js (由于jquery对跨域的请求做了限制,所以jquery仅限于在本域中使用。但为了快速解析XML文件,仍然可以使用jquery当成解析xml文件的工具。)。
2、通过js发起ajax请求。

总结:

如何通过ant发布第一个cxf应用。
手工建立一个java项目发布cxf的ws.
Java项目和js访问webService
加入消息拦截器
将服务端改为SOAP1.2实现
SOAP1.1与1.2

WebService-CXF-Spring基于web的cxf

开发cxf的web项目:

由于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的配置文件。

web.xml的配置如下:

 

Cxf-servlet.xml文件说明:

Cxf-servlet.xml文件,就是一个spring的配置文件。一个空的配置文件如下。

上面导入的三个配置文件都在cxf.jar的META文件夹中

在地址栏访问: -配置好空项目后,可以先测试是否可以启动成功:

http://localhost:9999/cxf_spring/ws

如果有WebService的存在,则会显示出来,如果没有,则会显示上而的信息。

如果有WebService的存在,则会显示出来,如果没有,则会显示上而的信息。

<?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:soap="http://cxf.apache.org/bindings/soap" xmlns:jaxrs="http://cxf.apache.org/jaxrs"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://cxf.apache.org/bindings/soap
http://cxf.apache.org/schemas/configuration/soap.xsd
http://cxf.apache.org/jaxws
http://cxf.apache.org/schemas/jaxws.xsd
http://cxf.apache.org/jaxrs
http://cxf.apache.org/schemas/jaxrs.xsd
">
<!-- 引入CXF Bean定义如下,早期的版本中使用 -->
<import resource="classpath:META-INF/cxf/cxf.xml" />
<import resource="classpath:META-INF/cxf/cxf-extension-soap.xml" />
<import resource="classpath:META-INF/cxf/cxf-servlet.xml" /> <!-- 方式一:简单发布,没有接口的发布方式 -->
<!--
id:当前服务的唯一标识 address:当前服务对应的请求url implementor:提供服务的类型
-->
<jaxws:endpoint id="helloService" address="/hello"
implementor="com.itheima.service.HelloService">
<!-- 添加客户端请求的消息拦截器 -->
<jaxws:inInterceptors>
<bean class="org.apache.cxf.interceptor.LoggingInInterceptor"></bean>
</jaxws:inInterceptors>
<!-- 添加服务端响应的消息拦截器 -->
<jaxws:outInterceptors>
<bean class="org.apache.cxf.interceptor.LoggingOutInterceptor"></bean>
</jaxws:outInterceptors>
</jaxws:endpoint> <!-- 方式二:带有接口的发布方式 -->
<!--
id:当前服务的唯一标识 address:当前服务对应的请求url serviceClass:接口类型
-->
<jaxws:server id="hiService" address="/hi"
serviceClass="com.itheima.service.IHiService">
<jaxws:serviceBean>
<bean class="com.itheima.service.HiServiceImpl" />
</jaxws:serviceBean>
<jaxws:inInterceptors>
<bean class="org.apache.cxf.interceptor.LoggingInInterceptor"></bean>
</jaxws:inInterceptors>
<jaxws:outInterceptors>
<bean class="org.apache.cxf.interceptor.LoggingOutInterceptor"></bean>
</jaxws:outInterceptors>
</jaxws:server> <!-- 发布一个Restful方式的WebService服务 -->
<bean id="personServiceImpl" class="com.itheima.service.PersonServiceImpl"></bean>
<jaxrs:server id="personService" address="/p">
<jaxrs:serviceBeans>
<ref bean="personServiceImpl" />
</jaxrs:serviceBeans>
<jaxrs:inInterceptors>
<bean class="org.apache.cxf.interceptor.LoggingInInterceptor"></bean>
</jaxrs:inInterceptors>
<jaxrs:outInterceptors>
<bean class="org.apache.cxf.interceptor.LoggingOutInterceptor"></bean>
</jaxrs:outInterceptors>
</jaxrs:server>
</beans>

cxf-servlet.xml

配置发布第一个ws : (jaxb)

发布带有接口的配置: (jax-ws)

必须要在声明为serviceClass的接口上声明@WebSerive注解
因为,要使用了接口,在接口上添加的注解才会有效。

配置说明:

CXFServlet类,通过读取config-location的配置项读取cxf-servlet.xml配置文件。并在内部读取自己的配置文件cxf.xml文件。
在CXFServlet读取配置文件后,将文件信息全部读取到ApplicationContext的Spring类中。
以下是它的源代码:

通过配置给服务添加消息拦截器:

LoggingInInterceptor
LogginOutInterceptor

在地址栏访问:

http://localhost:9999/cxf2.4_spring_web/ws

Java项目代码调用服务:

使用纯Java项目调用
1、根据客户端生成的代码来调用。(优选这种方式)
请先生成然后在任意的Java项目中调用 。
2、客户端只拥有一个接口,使用JaxWsProxyFactoryBean来调用。
因为以下使用了JaxWsProxyFactoryBean,所以,仍然需要CXF的环境,而使用此环境就会造成Jar文件的大量冗余,所以大家要谨慎选择。

在Spring项目中,通过配置文件调用:

以下是使用Spring的配置文件调用:
新建立一个Java项目,并加载cxf的所有包。
只需要生成的接口文件.
在classpath下新建立一个ClientBeans.xml文件.

优点与缺点:
此种情况,适合于一个Javaweb项目已经集成了Spring。并希望通过CXF配置的方式调用Web服务。
此种情况,仍然需要导入CXF的大量jar包。
这种情况也存在一定优点,如可以将外部的Web服务通过配置文件注入(DI)到Action类中。

建立好以后Java项目如下图

ClientBeans.xml文件的内容:

以下是调用代码:

关于web项目配置的说明1:

如果在项目中仅发布webservice,则可以只配置以下内容。
同时默认即是读取WEB-INF/cxf-servlet.xml文件,所以是否指定都可以。

关于web项目配置的说明2:

但一般情况下,一个web项目,在使用了Spring之后,往往会通过ApplicationContext获取一些服务,此时则必须注册Spring的监听器。即以下代码: 

见备注处,是一个完整的web.xml的配置。

关于web项目配置的说明3:

在上页中出现的重复引入问题,可以修改cxf-servlet.xml文件。
修改后,CXFServlet类将不能自动加载cxf-servlet.xml文件,此时将导致名为cxf的bean加载不成功。
为解决此问题必须在重新命名的配置文件中加入以下代码,以启动CXF:
即:如果你是用contextConfigLocation加载的配置文件,则必须要加入以下代码。

关于web项目配置的说明4:

在增加了Spring的监听器之后,即可以使用以下代码在Servlet中获取Spring的配置 :

通过JS来调用WebService:

通过jQuery的ajax方法向服务器发送xml数据。
必须要先了解xml的数据格式,通过拦截器获取。
可以从LoggingInInterceptor中获取发出的数据格式。
可以从LoggingOutInterceptor中获取返回的数据。
导入jQuery1.5.js文件,放到js/jquery1.5.js 

通过Ajax访问WebService

使用jQuery-本域

$.ajax({
url:..
type:’post’,
dataType:’xml’,
contentType:’application/soap+xml;charset=“UTF-”’
data:someXml,
Success:fun()…
})

在本域使用jquery访问:  --查询所有用户:

课程回顾:

什么是WebService?
在Jdk6上使用Endpoint发布WebService。
使用wsimport生成客户端代码。及各种监控工具的使用。
CXF的安装。
wsdl2java工具的使用。
CXF与spring进行整合。*
使用Ajax直接发送SOAP请求。

Web服务为我们带来了什么:SOA

(这是一种思想,不是简单的代码实现)

开发基于CXF的RESTFul Webservice

开发基于CXF的 RESTful WebService

.创建Web项目并导入CXF的jar
.在Web.xml中配置 CXFServlet
<servlet>
<servlet-name>cxf</servlet-name>
<servlet-class>org.apache.cxf.transport.servlet.CXFServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>cxf</servlet-name>
<url-pattern>/ws/*</url-pattern>
</servlet-mapping>
3.创建实体类 Person
@XmlRootElement(name = "person")
public class Person implements Serializable {
private String id;
private String name;
private String description;
@XmlElement(name = "id")
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
@XmlElement(name = "name")
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
@XmlElement(name = "description")
public String getDescription() {
return description;
}
public void setDescription(String description) {
this.description = description;
}
}
4.定义 PersonService 接口
//@Produces( { MediaType.APPLICATION_XML })
@Produces( { MediaType.APPLICATION_JSON })
public interface PersonService extends Serializable {
@GET
@Path("/persons")
public List<Person> getPersons(); @GET
@Path("/persons/{id}")
public Person getPerson(@PathParam("id") String id);
}
5.提供实现类 PersonServiceImpl
public class PersonServiceImpl implements PersonService {
private static final long serialVersionUID = 1L;
private static Map<String, Person> ps = new HashMap<String, Person>();
static {
Person info = new Person();
p1.setId("1");
p1.setName("zhangsan");
p1.setDescription("hello"); Person p1 = new Person();
p2.setId("2");
p2.setName("lisi");
p2.setDescription("lisi hehe"); ps.put(p1.getId(), p1);
ps.put(p2.getId(), p2);
} @Override
public Person getPerson(String id) {
return ps.get(id);
} @Override
public List<Person> getPersons() {
return new ArrayList(ps.values());
}
}
6.提供CXF 的配置文件 cxf-servlet.xml
<?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:jaxrs="http://cxf.apache.org/jaxrs"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
http://cxf.apache.org/jaxrs
http://cxf.apache.org/schemas/jaxrs.xsd">
<import resource="classpath:META-INF/cxf/cxf.xml" />
<import resource="classpath:META-INF/cxf/cxf-servlet.xml" />
<bean id="personService" class="cn.itcast.cxf.PersonServiceImpl" />
<jaxrs:server id="RestService" address="/v1">
<jaxrs:serviceBeans>
<ref bean="personService" />
</jaxrs:serviceBeans>
<jaxrs:inInterceptors>
<bean class="org.apache.cxf.interceptor.LoggingInInterceptor"></bean>
</jaxrs:inInterceptors>
<jaxrs:outInterceptors>
<bean class="org.apache.cxf.interceptor.LoggingOutInterceptor"></bean>
</jaxrs:outInterceptors>
</jaxrs:server>
</beans>
7.访问CXFServlet:http://localhost/CXF_01/ws
8.通过 URLConnection 访问WebService服务:
URLConnection conn = new URL("http://localhost/CXF_01/ws/v1/persons").openConnection();
HttpURLConnection con = (HttpURLConnection) conn;
con.setRequestMethod("GET");
int code = con.getResponseCode();
System.out.println(code);
InputStream is = con.getInputStream();
int len = 0;
byte[] b = new byte[1024];
StringBuffer sb = new StringBuffer();
while((len = is.read(b)) != -1){
String s = new String(b,0,len,"UTF-8");
sb.append(s);
}
System.out.println(sb.toString());
con.disconnect();

开发基于CXF的RESTFul Webservice

WebService-CXF 学习笔记的更多相关文章

  1. WebService CXF学习:复杂对象传递(List,Map)

    转自:https://blog.csdn.net/z69183787/article/details/35988335 第一步:创建存储复杂对象的类(因为WebServices的复杂对象的传递,一定要 ...

  2. webService cxf学习

    1.首先去官网下载cxf包 http://archive.apache.org/dist/cxf/ 记住要选.zip结尾 大概40兆的样子 2.把上边的包都放项目里.如果你用的jeecg框架,那它自带 ...

  3. webservice系统学习笔记10-使用jax-ws创建基于tomcat类型的容器的ws服务

    1.在web-info目录下新建目录wsdl 2.在1步的目录下 新建文件user.wsdl <?xml version="1.0" encoding="UTF-8 ...

  4. webservice系统学习笔记9-使用契约优先的方式的一个服务端demo(隐式传Header信息)

    服务器端: 1.编写wsdl文件 <?xml version="1.0" encoding="UTF-8" standalone="no&quo ...

  5. webservice系统学习笔记7-使用handler实现过滤器/拦截器效果

    handler可以作用于客户端,也可以作用了服务端 handler分为:1.LogicalHandler:只能获取到soap消息的body. 2.SOAPHandler:可以获取SOAPMessage ...

  6. webservice系统学习笔记5-手动构建/发送/解析SOAP消息

    手动拼接SOAP消息调用webservice SOAP消息的组成: 1.创建需要发送的SOAP消息的XML(add方法为例子) /** * 创建访问add方法的SOAP消息的xml */ @Test ...

  7. webservice系统学习笔记4-使用工具查看SOAP消息

    使用myeclipse的WTP java ee视图里的[web services Explorer]来测试查看webservice传输的SOAP消息 1. 2. 测试getUserByUsername ...

  8. webservice系统学习笔记2-使用jdk的命令生成本地代码

    使用jdk自带的命令wsimport生成远程服务的本地代码 C:\Documents and Settings\Administrator>wsimport -d E:\mhWorkspace\ ...

  9. webservice系统学习笔记1-使用注解创建ws服务

    简单入门之helloword,具体详细的在后面的章节详细介绍. 使用JDK自带的jax-ws创建并发布一个简单的webservice 在本地创建服务,然后本机访问 1.创建服务提供接口 IMyServ ...

  10. CXF学习笔记 之 “注解”

    @WebService 1.serviceName: 对外发布的服务名,指定 Web Service 的服务名称:wsdl:service.缺省值为 Java 类的简单名称 + Service.(字符 ...

随机推荐

  1. 吴裕雄 python 机器学习——KNN回归KNeighborsRegressor模型

    import numpy as np import matplotlib.pyplot as plt from sklearn import neighbors, datasets from skle ...

  2. python 第三方库安装

    1.首先安装pip 2.在cmd中找到pip的安装路径,(一般在python的scripts文件中) 3.pip install 第三方库名称

  3. redis集群(Sentinel)

    问题 Redis 主哨兵模式是如何保证高可用的 主要依赖主哨兵的发现故障和故障转移 概述 本文假设读者对redis 的主从复制已经进行了了解 . Redis 主哨兵集群为Redis 提供了高可用,即高 ...

  4. Git - Windows 下, gitbash 打开资源管理器

    1. 概述 windows 下 gitbash 打开 资源管理器 2. 场景 资源管理唤起 gitbash 步骤 进入目录 鼠标右击 在 弹出菜单 中, 找到 Git Bash Here 结果 打开一 ...

  5. 【Python redis】

    目录 基本用法 连接池 基本命令 String Hash List set "下载:pip install redis @ *** 基本用法 redis库提供两个类,Redis和Strict ...

  6. awk基本介绍

    AWK 是一种用于处理文本的编程语言工具.awk经过改进生成的新的版本nawk,gawk,现在默认linux系统下日常使用的是gawk,用命令可以查看正在应用的awk的来源(ls -l /bin/aw ...

  7. requests使用小结(不定期更新)

    request是python的第三方库,使用上比urllib和urllib2要更方便. 0x01 使用session发送:能保存一条流中获取的cookie,并自动添加到http头中 s = reque ...

  8. BZOJ-1563-郁闷的出纳员(权值线段树)

    偏移量要考虑清楚. #include <bits/stdc++.h> using namespace std; const int N=4e5+10; const int BASE=1e5 ...

  9. vue axios路由跳转取消所有请求 和 防止重复请求

    直接上干货 在发送第二次请求的时候如果第一次请求还未返回,则取消第一次请求,以保证后发送的请求返回的数据不会被先发送的请求覆盖. 或者是跳转路由的时候取消还未返回的请求 第一步: axios 怎么取消 ...

  10. 【PAT甲级】1101 Quick Sort (25 分)

    题意: 输入一个正整数N(<=1e5),接着输入一行N个各不相同的正整数.输出可以作为快速排序枢纽点的个数并升序输出这些点的值. trick: 测试点2格式错误原因:当答案为0时,需要换行两次