Apache CXF = Celtix + XFire,开始叫 Apache CeltiXfire,后来更名为 Apache CXF 了,以下简称为 CXF。CXF 继承了 Celtix 和 XFire 两大开源项目的精华,提供了对 JAX-WS 全面的支持,并且提供了多种 Binding 、DataBinding、Transport 以及各种 Format 的支持,并且可以根据实际项目的需要,采用代码优先(Code First)或者 WSDL 优先(WSDL First)来轻松地实现 Web Services 的发布和使用。Apache CXF已经是一个正式的Apache顶级项目。
简单来说CXF就是用来被发布一个WebService类的
1,开发第一个CXF的web应用程序
其中一个核心类是:JaxWsServiceFactoryBean - 它替代了EndPoint类,用于发布一个基于jax-ws 的 webService
第一步:添加jar包
cxf-2.6.1.jar
jetty-continuation-7.4.5.v20110725.jar
jetty-http-7.4.5.v20110725.jar
jetty-io-7.4.5.v20110725.jar
jetty-server-7.4.5.v20110725.jar
jetty-security-7.4.5.v20110725.jar
jetty-util-7.4.5.v20110725.jar
neethi-3.0.1.jar
servlet-api.jar
wsdl4j-1.6.2.jar
xmlschema-core-2.0.1.jar
其中jetty其实就相当于一个容器,类似tomcat一样
第二步;
CXF发布一个webServie类
@WebService
//采用sope 1.1 协议
@BindingType(javax.xml.ws.soap.SOAPBinding.SOAP11HTTP_BINDING)
public class HelloWorld {
/**
* 至少应该包含一个对外公开的方法
*/
public String sayHi(String name){
System.err.println("服务器:"+name);
return "你好,时间为:"+new Date()+","+name;
}
/**
* CXF发布一个webService
* 注释了的 是用 EndPoint 发布的一个webService
*
*/
public static void main(String[] args) {
//用CXF的发布类,基于jax-ws的服务
JaxWsServerFactoryBean bean =
new JaxWsServerFactoryBean();
//设置服务类
bean.setServiceBean(new HelloWorld());
//3:设置服务的地址和端口
bean.setAddress("http://192.168.0.70:8080/hello");
//4:启动服务,内部开启jetty这个容器
Server ss = bean.create();
System.err.println("发布成功。。。。");
//Endpoint.publish("http://192.168.1.100:8888/hello", new HelloWorld());//jax-ws
}
第三步:
客户端调用webService
命令行输入:wsimport -s . http://192.168.0.70:8080/hello?wsdl ,将生成的代码拷贝到项目中
调用代码:
public static void main(String[] args) {
HelloWorld hw =
new HelloWorldService().getHelloWorldPort();
String str = hw.sayHi("张三");
System.err.println(str);
}
第四步:
将服务器端的webservice注解改成如下方式,就是soap1.2协议
@BindingType(javax.xml.ws.soap.SOAPBinding.SOAP12HTTP_BINDING)
但是注意: jdk提供的wsimport方式只支持生成 soap1.1的方式,所以用wsimport生成soap1.2服务器端代码时会出错。
第五步:
eclipse和Myeclipse本身提供了一个插件,可以拦截请求获取一个请求soap1.2所发送的xml文本 window --》show view --》 TCP/IP Monitor
因为这里不能贴图,这不就略了 ,下面是获取的xml文本
以下是拦截到的请求soap12:
<?xml version="1.0" ?>
<S:Envelope
xmlns:S="http://www.w3.org/2003/05/soap-envelope "><S:Body>
<ns2:sayHi xmlns:ns2="http://ws.itcast.cn/"><arg0>Jack</arg0></ns2:sayHi></S:Body>
</S:Envelope>
以下是拦截到的响应的soap12:
<soap:Envelope
xmlns:soap="http://www.w3.org/2003/05/soap-envelope "><soap:Body>
<ns1:sayHiResponse xmlns:ns1="http://ws.itcast.cn/">
<return>Wed Nov 14 10:13:49 CST 2012,Jack</return></ns1:sayHiResponse>
</soap:Body></soap:Envelope>
拦截soap1.1
<?xml version="1.0" ?>
<S:Envelope
xmlns:S="http://schemas.xmlsoap.org/soap/envelope/ ">
<S:Body><ns2:sayHi xmlns:ns2="http://ws.itcast.cn/">
<arg0>Name </arg0></ns2:sayHi></S:Body>
</S:Envelope>
拦截到的soap11响应:
<soap:Envelope
xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/ "><soap:Body><ns1:sayHiResponse xmlns:ns1="http://ws.itcast.cn/"><return>
Wed Nov 14 10:17:52 CST 2012,Jack</return>
</ns1:sayHiResponse></soap:Body></soap:Envelope>
第六步:测试
用ajax向soap1.1的服务发11请求,和发12请求。
用ajax向soap12发11的请求和12的请求。
<html>
<script type="text/javascript" src="jquery-1.8.2.js"></script>
<body>
<input type="text" id="name"><br/>
<button id="btn">Send</button>
<button id="btn2">Send_Soap12</button>
</body>
<script type="text/javascript">
$(function(){
var xhr = new ActiveXObject("Microsoft.XMLHttp");
$("#btn").click(function(){
var url = "http://192.168.0.70:8080/hello";
xhr.open("POST",url,true);
xhr.setRequestHeader("Content-Type","text/xml;charset=UTF-8");
xhr.onreadystatechange=function(){
if(xhr.readyState==4){
if(xhr.status==200){
var xml = xhr.responseText;
alert(xml);
}
}
};
var nm = $("#name").val();
var xml = '<soap12:Envelope xmlns:soap12="http://schemas.xmlsoap.org/soap/envelope/">'+
'<soap12:Body><ns2:sayHi xmlns:ns2="http://ws.itcast.cn/">'+
'<arg0>'+nm+'</arg0></ns2:sayHi></soap12:Body></soap12:Envelope>';
alert("发送的是:"+xml);
xhr.send(xml);
});
//soap1.2
$("#btn2").click(function(){
var url = "http://192.168.0.70:8080/hello";
xhr.open("POST",url,true);
xhr.setRequestHeader("Content-Type","application/soap+xml;charset=UTF-8");
xhr.onreadystatechange=function(){
if(xhr.readyState==4){
if(xhr.status==200){
var xml = xhr.responseText;
alert(xml);
}
}
};
var nm = $("#name").val();
var xml= '<S:Envelope xmlns:S="http://www.w3.org/2003/05/soap-envelope"><S:Body>'+
'<ns2:sayHi xmlns:ns2="http://ws.itcast.cn/">'+
'<arg0>'+nm+'</arg0></ns2:sayHi></S:Body></S:Envelope>';
xhr.send(xml);
});
});
</script>
</html>
第七步:
还有一种方式 是用来 提来 jdk不能提供soap1.2 的 工具
在cxf安装包中,提供了wsdl2java.bat这个工具,它可以解析soap1.2的wsdl和soap1.2的wsdl
生成webService服务器端代码的方式:
第一种:用wsimport生成本地调用代码,只支持soap1.1的生成 代码。
第二种:用ajax获取soap文件,自己发送去调用。Jquery去解析
第三种:用URLConnection发送soap文本调用。用dom去解析
第四种:用wsdl2java生成本的调用代码。即支持1.1也支持1.2。
2, 发布一个Jax-RS的webService
JAX-RS的意思是 静态地址参数转换,http://localhost:8080/hello/jack/80
核心类:
JAXRSServiceFactoryBean
Jas-rs不支持返回字符串类型的数据,支持的是List<Bean>,List<String>,List<Map>,Bean,Map
它的注解分为以以下的注解:
@Path– 说明webservice的路径信息,@Path(value=”/user/”)
@Get – 说明某个方法只支持get请求。
@Post – 说明某个方法中支持poost请求。
@PathParam – 说明引用路径中的哪一个信息为变量
@FormParam – 如果为post类型,则说明引用哪一个表单中的变量。
@Produces – 设置返回的是xml数据还是json数据
还有用于设置返回的bean的根元素是什么名:
@RootElement
再倒入两个jar包:
jsr311-api-1.1.1.jar
jettison-1.3.jar
@Path(value="/greeting/")
@Produces(value={"application/xml","application/json"})
public class Greeting {
@GET
@Path(value="/hello/{nm}")
public User hello(@PathParam(value="nm")String name){
System.err.println("服务器输出的是:"+name);
User u = new User();
u.setName("你好:"+name+","+new Date());
return u;
}
public static void main(String[] args) {
JAXRSServerFactoryBean bean =
new JAXRSServerFactoryBean();
bean.setServiceBean(new Greeting());
bean.setAddress("http://192.168.0.70:8080");
bean.create();
System.err.println("启动成功。。。");
}
}
访问
获取wsdl文件:
http://192.168.0.70:8080/greeting?_wadl&_type=xml
ajax反方式访问:
<html>
<script type="text/javascript" src="jquery-1.8.2.js"></script>
<body>
<button id="btn">Btn1</button>
<button id="btn2">Btn2</button>
</body>
<script type="text/javascript">
$("#btn").click(function(){
var xhr = new ActiveXObject("Microsoft.XMLHttp");
var url = "http://192.168.0.70:8080/greeting/hello/Jack/22/";
xhr.open("GET",url,true);
xhr.setRequestHeader("accept","application/json");//决定了服务器返回什么类型的数据
xhr.onreadystatechange=function(){
if(xhr.readyState==4){
if(xhr.status==200){
var txt = xhr.responseText;
alert(txt);
}
}
};
xhr.send(null);
});
$("#btn2").click(function(){
var xhr = new ActiveXObject("Microsoft.XMLHttp");
var url = "http://192.168.0.70:8080/greeting/save";
xhr.open("POST",url,true);
xhr.setRequestHeader("accept","application/xml");//决定了服务器返回什么类型的数据
xhr.setRequestHeader("Content-Type","application/x-www-form-urlencoded");
xhr.setRequestHeader("Content-Encoding","UTF-8");
xhr.onreadystatechange=function(){
if(xhr.readyState==4){
if(xhr.status==200){
var txt = xhr.responseText;
alert(txt);
}
}
};
var param = "name=李四同学&age=90";
//param = encodeURI(param);
xhr.send(param);
});
</script>
</html>