什么是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的其他支持项目:
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
在Eclipse中开发CXF的JavaSE应用:
导入CXF中的 所有jar文件。可以通过WACH_JARS来观察各jar文件的用途。
建立好之后的项目如图所示:
CXF发布服务的类:
用两个不同的类发布应用:
Serverfactorybean -- FacotryBean
JaxWsServerfactorybean(建议使用此类)
使用Serverfactorybean发布服务:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
|
/**
* 使用Serverfactorybean发布CXF的javase应用
* @author zhaoqx
*
*/
public
class
HelloService {
public
String sayHello(String name){
return
"hello "
+ name;
}
public
static
void
main(String[] args) {
bean.setAddress(
"http://192.168.1.24:9999/Hello"
);
bean.setServiceClass(HelloService.
class
);
bean.setServiceBean(
new
HelloService());
bean.create();
}
}
|
使用ClientProxyfactorybean客户端调用
使用Serverfactorybean发布服务以后,在没有接口的情况下,可以使用wsimport生成的客户端代码调用成功。
但如果要使用ClientProxyfactorybean客户端去调用服务器,则必须要先在服务器端创建一个接口。(一直以来,Spring都要求面向接口编程,而cxf与Spring能很好的整合,也就在此。),所以,必须要重写服务器端的代码。这将导致刚才使用wsimport生成的调用代码失效。
同时, ClientProxyfactorybean由于要用到CXF环境,所以要导入CXF的所有包。
同时,如果是在本项目中调用,则可以直接使用本项目的接口。
如果在其他项目中调用,仍然需wsimport生成的类,但只需要一个接口。
使用JaxWsServerfactorybean发布服务: (建议使用此类)
JaxWsServerfactorybean是Serverfactorybean的子类,也是功能扩展类。但在CXF的api文档中没有提供此类API,请通过查看源代码的方式获取此类的帮助。此类,必须要在被发布为服务的类上添加@WebService注解,如果不加注解,虽然不出错,但也不会对外暴露任何方法。使用此类生成的wsdl文件更加规范。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
|
@WebService
public
class
HiService {
public
String sayHi(String name){
return
"Hi"
+name;
}
public
static
void
main(String[] args) {
bean.setAddress(
"http://localhost:9999/two"
);
bean.setServiceClass(HiService.
class
);
bean.setServiceBean(
new
HiService());
bean.create();
}
}
|
使用JaxWsProxyfactorybean客户端调用:
此调用过程与ClientProxyfactorybean的要求一样,也必须要拥有一个接口。
此时,仍然可以使用wsimport生成接口,在其他项目的调用。
规范的做法应该是先书写一个接口,如下:
1
2
3
4
|
@WebService
public
interface
IHelloService {
public
String sayHello(String name);
}
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
|
public
class
IHelloServiceImpl
implements
IHelloService {
public
String sayHello(String name) {
SimpleDateFormat sdf =
new
SimpleDateFormat(
"yyyy-MM-dd HH:mm:ss"
);
return
sdf.format(
new
Date())+
"=== hello====="
+ name;
}
public
static
void
main(String[] args) {
bean.setAddress(
"http://192.168.1.24:8888/sayHi"
);
bean.setServiceClass(IHelloService.
class
);
bean.setServiceBean(
new
IHelloServiceImpl());
//加入请求消息拦截器
//加入响应消息拦截器
bean.create();
}
}
|
在cxf中,也提供了一个用于生成客户端调用代码的工具。它的功能就如同wsimport一样。
先让我们了解一下cxf的wsdl2java工具,可以生成一堆客户端调用的代码。
此工具位于cxf_home/bin目录下。参数与wsimport有所不同。
它包含以下参数:
-p参数,指定生成的新的包结构。
需要说明的是,由于wsdl2java是根据jdk1.7生成的本地代码,所以,需要对生成的代码做一点点修改。
在命令行执行:
wsdl2java –d . http://127.0.0.1:6666/helloworld?wsdl
使用JavaScript也可以访问WebServie:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
|
<!DOCTYPE HTML PUBLIC
"-//W3C//DTD HTML 4.01 Transitional//EN"
>
<html>
<head>
<title>使用jquery的ajax调用Web服务 </title>
<script type=
"text/javascript"
src=
"js/jquery-1.6.2.js"
></script>
<script type=
"text/javascript"
>
$(
function
(){
$(
"#but1"
).click(
function
(){
//指定访问服务的地址
var
wsUrl =
"http://localhost:8090/CXF03/cxf/hi"
;
//构造请求体
var
soap =
'<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/"><soap:Body><ns2:sayHi xmlns:ns2="http://kaiyi/"><arg0>abc</arg0></ns2:sayHi></soap:Body></soap:Envelope>'
;
$.ajax({
url:wsUrl,
type:
'post'
,
dataType:
'xml'
,
contentType:
'text/xml;charset=UTF-8'
,
data:soap,
success:
function
(data){
alert(
'OK!'
);
var
o = $(data);
alert(o.find(
'return'
).eq(0).text());
},
error:
function
(){
alert(
'error!'
);
}
});
});
});
</script>
</head>
<body>
<input type=
"button"
value=
"发送jquery的ajax请求"
id=
"but1"
>
</body>
</html>
|
以上均是非WEB的开发下面介绍基于web的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的配置文件。
cxf-servlet.xml:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
|
<?
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定义如下,早期的版本中使用 -->
<!-- 通过spring配置文件发布CXF的服务 -->
<!-- 第一种发布方式:没有接口的发布(简单发布) -->
<!--
id:唯一标识
address:访问url
implementor:提供服务的类型
-->
<
jaxws:endpoint
id
=
"helloService"
address
=
"/hello"
implementor
=
"kaiyi.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
>
<!-- 第二种发布方式:带有接口的发布 -->
<
jaxws:server
id
=
"hiService"
address
=
"/hi"
serviceClass
=
"kaiyi.IHiService"
>
<
jaxws:serviceBean
>
<!-- 提供服务的实现类 -->
<
bean
class
=
"kaiyi.IHiServiceImpl"
></
bean
>
</
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方式的web服务 -->
<
bean
id
=
"ps"
class
=
"restful.PersonServiceImpl"
></
bean
>
<
jaxrs:server
id
=
"personService"
address
=
"/p"
>
<
jaxrs:serviceBeans
>
<
ref
bean
=
"ps"
/>
</
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
>
|
web.xml
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
|
<?
xml
version
=
"1.0"
encoding
=
"UTF-8"
?>
<
web-app
version
=
"2.5"
xmlns
=
"http://java.sun.com/xml/ns/javaee"
xmlns:xsi
=
"http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee
http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd">
<!-- 通过上下文参数指定spring配置文件的位置 -->
<
listener
>
<
listener-class
>org.springframework.web.context.ContextLoaderListener</
listener-class
>
</
listener
>
<!-- 配置CXF框架的核心Servlet -->
<
servlet
>
<
servlet-name
>cxf</
servlet-name
>
<
servlet-class
>org.apache.cxf.transport.servlet.CXFServlet</
servlet-class
>
<!-- 通过初始化参数指定配置文件的位置 -->
<!--
<init-param>
</init-param>-->
</
servlet
>
<
servlet-name
>cxf</
servlet-name
>
<
url-pattern
>/cxf/*</
url-pattern
>
</
web-app
>
|
这是我的包结构:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
|
/**
* 使用Serverfactorybean发布CXF的javase应用
* @author zhaoqx
*
*/
@WebService
public
class
HelloService {
public
String sayHello(String name){
return
"hello "
+ name;
}
}
|
1
2
3
4
5
6
7
8
|
package
kaiyi;
import
javax.jws.WebService;
@WebService
public
interface
IHiService {
public
String sayHi(String name);
}
|
1
2
3
4
5
6
7
8
9
10
|
package
kaiyi;
public
class
IHiServiceImpl
implements
IHiService{
public
String sayHi(String name) {
return
"hi "
+ name;
}
}
|
在地址栏访问:
Java项目代码调用服务:
使用纯Java项目调用
1、根据客户端生成的代码来调用。(优选这种方式)请先生成然后在任意的Java项目中调用 。
2、客户端只拥有一个接口,使用JaxWsProxyfactorybean来调用。
因为以下使用了JaxWsProxyfactorybean,所以,仍然需要CXF的环境,而使用此环境就会造成Jar文件的大量冗余,所以大家要谨慎选择(一下的地址是随便贴的)。
新建立一个Java项目,并加载cxf的所有包。
在classpath下新建立一个ClientBeans.xml文件.
优点与缺点:
此种情况,适合于一个Javaweb项目已经集成了Spring。并希望通过CXF配置的方式调用Web服务。
此种情况,仍然需要导入CXF的大量jar包。
这种情况也存在一定优点,如可以将外部的Web服务通过配置文件注入(DI)到Action类中。
结构图如下(带接口的方式):
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
|
<?
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"
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">
<!-- 配置客户端bean -->
<!--
id:唯一标识
address:请求的服务地址
serviceClass:客户端接口
-->
<
jaxws:client
id
=
"hiService"
address
=
"http://localhost:8090/CXF03/cxf/hi"
serviceClass
=
"kaiyi.IHiService"
></
jaxws:client
>
</
beans
>
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
|
package test;
import kaiyi.IHiService;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClasspathXmlApplicationContext;
public class test {
public static void main(String[] args) {
ApplicationContext ctx = new ClasspathXmlApplicationContext("ClientBeans.xml");
IHiService ihi = (IHiService) ctx.getBean("hiService");
ihi.sayHi("abc");
System.out.println(ihi.getClass().getName());
}
}
|
通过JS来调用WebService:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
|
<!DOCTYPE HTML PUBLIC
"-//W3C//DTD HTML 4.01 Transitional//EN"
>
<html>
<head>
<title>使用jquery的ajax调用Web服务 </title>
<script type=
"text/javascript"
src=
"js/jquery-1.6.2.js"
></script>
<script type=
"text/javascript"
>
$(
function
(){
$(
"#but1"
).click(
function
(){
//指定访问服务的地址
var
wsUrl =
"http://localhost:8090/CXF03/cxf/hi"
;
//构造请求体
var
soap =
'<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/"><soap:Body><ns2:sayHi xmlns:ns2="http://kaiyi/"><arg0>abc</arg0></ns2:sayHi></soap:Body></soap:Envelope>'
;
$.ajax({
url:wsUrl,0); font-size:16px">POJO类:
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 [email protected] 举报,一经查实,本站将立刻删除。 相关推荐 |