博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
CXF开发webservice
阅读量:7171 次
发布时间:2019-06-29

本文共 14141 字,大约阅读时间需要 47 分钟。

hot3.png

什么是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文件的用途。

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

154104_oef2_1425737.png

CXF发布服务的类:

用两个不同的类发布应用:

            ServerFactoryBean   -- FacotryBean

            JaxWsServerFactoryBean(建议使用此类)

154238_LZUs_1425737.png

使用ServerFactoryBean发布服务:

    

/** * 使用ServerFactoryBean发布CXF的javase应用 * @author zhaoqx * */public class HelloService {		public String sayHello(String name){		System.out.println("sayHello called...");		return "hello " + name;	}	public static void main(String[] args) {		ServerFactoryBean bean = new ServerFactoryBean();		bean.setAddress("http://192.168.1.24:9999/Hello");		bean.setServiceClass(HelloService.class);		bean.setServiceBean(new HelloService());		bean.create();		System.err.print("启动成功");	}}

使用ClientProxyFactoryBean客户端调用

使用ServerFactoryBean发布服务以后,在没有接口的情况下,可以使用wsimport生成的客户端代码调用成功。

但如果要使用ClientProxyFactoryBean客户端去调用服务器,则必须要先在服务器端创建一个接口。(一直以来,Spring都要求面向接口编程,而cxf与Spring能很好的整合,也就在此。),所以,必须要重写服务器端的代码。这将导致刚才使用wsimport生成的调用代码失效。

同时, ClientProxyFactoryBean由于要用到CXF环境,所以要导入CXF的所有包。

同时,如果是在本项目中调用,则可以直接使用本项目的接口。

如果在其他项目中调用,仍然需wsimport生成的类,但只需要一个接口。

154741_HKir_1425737.png

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

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

@WebService//@javax.xml.ws.BindingType(value=javax.xml.ws.soap.SOAPBinding.SOAP12HTTP_BINDING)public class HiService {	public String sayHi(String name){		System.out.println("服务调用");		return "Hi"+name;	}	public static void main(String[] args) {		JaxWsServerFactoryBean bean = new JaxWsServerFactoryBean();		bean.setAddress("http://localhost:9999/two");		bean.setServiceClass(HiService.class);		bean.setServiceBean(new HiService());		bean.create();		System.err.print("服务启动成功");	}}

使用JaxWsProxyFactoryBean客户端调用:

此调用过程与ClientProxyFactoryBean的要求一样,也必须要拥有一个接口。

此时,仍然可以使用wsimport生成接口,在其他项目的调用。

155158_txYO_1425737.png

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

@WebServicepublic interface IHelloService {	public String sayHello(String name);}
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) {		JaxWsServerFactoryBean bean = new JaxWsServerFactoryBean();		bean.setAddress("http://192.168.1.24:8888/sayHi");		bean.setServiceClass(IHelloService.class);		bean.setServiceBean(new IHelloServiceImpl());		//加入请求消息拦截器		bean.getInInterceptors().add(new LoggingInInterceptor());		//加入响应消息拦截器		bean.getOutInterceptors().add(new LoggingOutInterceptor());		bean.create();		System.err.print("服务启动成功");	}}

wsdl2java生成客户代码:

在cxf中,也提供了一个用于生成客户端调用代码的工具。它的功能就如同wsimport一样。

先让我们了解一下cxf的wsdl2java工具,可以生成一堆客户端调用的代码。

此工具位于cxf_home/bin目录下。参数与wsimport有所不同。

它包含以下参数:

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

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

需要说明的是,由于wsdl2java是根据jdk1.7生成的本地代码,所以,需要对生成的代码做一点点修改。

在命令行执行:

wsdl2java –d .

调用端代码:

155602_cuxj_1425737.png

使用JavaScript也可以访问WebServie:

      使用jquery的ajax调用Web服务     
    
     $(function(){     $("#but1").click(function(){     //指定访问服务的地址     var wsUrl = "http://localhost:8090/CXF03/cxf/hi";     //构造请求体     var soap = '
abc
';     $.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!'); } });     });     });              
  

以上均是非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:

web.xml

contextConfigLocation
classpath:cxf-servlet.xml
org.springframework.web.context.ContextLoaderListener
cxf
org.apache.cxf.transport.servlet.CXFServlet
 
cxf
/cxf/*
  
    
index.jsp
  

这是我的包结构:

160510_EPn6_1425737.png

/** * 使用ServerFactoryBean发布CXF的javase应用 * @author zhaoqx * */@WebServicepublic class HelloService {		public String sayHello(String name){		System.out.println("sayHello called...");		return "hello " + name;	}	}

package kaiyi;import javax.jws.WebService;@WebServicepublic interface IHiService {	public String sayHi(String name);}
package kaiyi;public class IHiServiceImpl implements  IHiService{	public String sayHi(String name) {		System.out.println("sayHi....");		return "hi " + name;	}}

            

在地址栏访问:

160924_KZtA_1425737.png

Java项目代码调用服务:

使用纯Java项目调用

1、根据客户端生成的代码来调用。(优选这种方式)请先生成然后在任意的Java项目中调用 。

2、客户端只拥有一个接口,使用JaxWsProxyFactoryBean来调用。

因为以下使用了JaxWsProxyFactoryBean,所以,仍然需要CXF的环境,而使用此环境就会造成Jar文件的大量冗余,所以大家要谨慎选择(一下的地址是随便贴的)。

161247_7MTF_1425737.png

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

以下是使用Spring的配置文件调用:

新建立一个Java项目,并加载cxf的所有包。

只需要生成的接口文件.

在classpath下新建立一个ClientBeans.xml文件.

优点与缺点:

        此种情况,适合于一个Javaweb项目已经集成了Spring。并希望通过CXF配置的方式调用Web服务。

        此种情况,仍然需要导入CXF的大量jar包。

        这种情况也存在一定优点,如可以将外部的Web服务通过配置文件注入(DI)到Action类中。

结构图如下(带接口的方式):

161555_sBE4_1425737.png

ClientBeans.xml文件的内容:

以下是调用代码:

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:

      使用jquery的ajax调用Web服务     
    
     $(function(){     $("#but1").click(function(){     //指定访问服务的地址     var wsUrl = "http://localhost:8090/CXF03/cxf/hi";     //构造请求体     var soap = '
abc
';     $.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!'); } });     });     });              
  

POJO类:

package pojo;import java.io.Serializable;import javax.xml.bind.annotation.XmlElement;import javax.xml.bind.annotation.XmlRootElement;@XmlRootElement(name = "person")public class Person implements Serializable{	/**	 * 	 */	private static final long serialVersionUID = 1L;	private String id;	private String name;	private String desc;		@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 = "desc")	public String getDesc() {		return desc;	}	public void setDesc(String desc) {		this.desc = desc;	}	@Override	public String toString() {		return "Person [desc=" + desc + ", id=" + id + ", name=" + name + "]";	}		}

现在一般来说用URL的方式调用restful服务比较流行:

它与WSDL方式完全不同,采用的是一种新型的方式,企业开发使用较为常见:

Available RESTful services:

Endpoint address: http://localhost:8090/CXF03/cxf/p
WADL :

访问后返回的是json或者XML数据

此种方式只需要在cxf-servlet.xml配置一下即可:

以下是访问方式:

package test;import java.io.InputStream;import java.net.HttpURLConnection;import java.net.URL;import java.net.URLConnection;import java.util.List;import net.sf.json.JSONArray;import net.sf.json.JSONObject;import org.junit.Test;import pojo.Person;// 使用URL的方式调用restful服务public class UrlConnectionTest {		@Test	public void test1() throws Exception {		String wsUrl = "http://localhost:8090/CXF03/cxf/p/persons/id0";		URL url = new URL(wsUrl);				URLConnection conn = url.openConnection();		HttpURLConnection con = (HttpURLConnection)conn;				con.setRequestMethod("GET");		int code = con.getResponseCode();		if(code == 200){			InputStream in = con.getInputStream();			byte[] b = new byte[1024];			int len = 0;			StringBuffer sb = new StringBuffer();			while((len=in.read(b))!=-1){				String s = new String(b,0,len,"UTF-8");				sb.append(s);			}			String json = sb.toString();			JSONObject o = JSONObject.fromObject(json);			json = o.getString("person").toString();			//将String转换为Person对象			Person person = (Person) JSONObject.toBean(JSONObject.fromObject(json), Person.class);			System.out.println("----"+person);		}		con.disconnect();	}			@Test	public void test2() throws Exception {		String wsUrl = "http://localhost:8090/CXF03/cxf/p/persons";		URL url = new URL(wsUrl);				URLConnection conn = url.openConnection();		HttpURLConnection con = (HttpURLConnection)conn;				con.setRequestMethod("GET");		int code = con.getResponseCode();		if(code == 200){			InputStream in = con.getInputStream();			byte[] b = new byte[1024];			int len = 0;			StringBuffer sb = new StringBuffer();			while((len=in.read(b))!=-1){				String s = new String(b,0,len,"UTF-8");				sb.append(s);			}			String json = sb.toString();			JSONObject o = JSONObject.fromObject(json);			Object obj = o.get("person");			json = obj.toString();					List
 list = (List
)JSONArray.toCollection(JSONArray.fromObject(json), Person.class); for(Person p:list){ System.out.println(p); } } con.disconnect(); }}

我们可以根据被调用服务的接口上的注解来决定返回值的数据格式

//@Produces( { MediaType.APPLICATION_XML })

@Produces( { MediaType.APPLICATION_JSON })

public interface IPersonService extends Serializable 

以下是服务代码:

package restful;import java.io.Serializable;import java.util.List;import javax.ws.rs.GET;import javax.ws.rs.Path;import javax.ws.rs.PathParam;import javax.ws.rs.Produces;import javax.ws.rs.core.MediaType;import pojo.Person;//@Produces( { MediaType.APPLICATION_XML })@Produces( { MediaType.APPLICATION_JSON })public interface IPersonService extends Serializable {		@GET	@Path(value="/persons/{id}")	public Person findPersonById(			@PathParam("id")			String id);		@GET	@Path(value="/persons")	public List
 findAllPerson();}
package restful;import java.util.ArrayList;import java.util.HashMap;import java.util.List;import java.util.Map;import pojo.Person;public class PersonServiceImpl implements IPersonService {	/**	 * 	 */	private static final long serialVersionUID = 1L;	private static Map
 ps = new HashMap
(); static { for(int i=0;i<5;i++){ Person p = new Person(); p.setId("id" + i); p.setName("person" + i); p.setDesc("desc" + i); ps.put(p.getId(), p); } } public List
 findAllPerson() { return new ArrayList
(ps.values()); } public Person findPersonById(String id) { return ps.get(id); } }

以下是调用代码:

package test;import java.io.InputStream;import java.net.HttpURLConnection;import java.net.URL;import java.net.URLConnection;import java.util.List;import net.sf.json.JSONArray;import net.sf.json.JSONObject;import org.junit.Test;import pojo.Person;// 使用URL的方式调用restful服务public class UrlConnectionTest {		@Test	public void test1() throws Exception {		String wsUrl = "http://localhost:8090/CXF03/cxf/p/persons/id0";		URL url = new URL(wsUrl);				URLConnection conn = url.openConnection();		HttpURLConnection con = (HttpURLConnection)conn;				con.setRequestMethod("GET");		int code = con.getResponseCode();		if(code == 200){			InputStream in = con.getInputStream();			byte[] b = new byte[1024];			int len = 0;			StringBuffer sb = new StringBuffer();			while((len=in.read(b))!=-1){				String s = new String(b,0,len,"UTF-8");				sb.append(s);			}			String json = sb.toString();			JSONObject o = JSONObject.fromObject(json);			json = o.getString("person").toString();			//将String转换为Person对象			Person person = (Person) JSONObject.toBean(JSONObject.fromObject(json), Person.class);			System.out.println("----"+person);		}		con.disconnect();	}			@Test	public void test2() throws Exception {		String wsUrl = "http://localhost:8090/CXF03/cxf/p/persons";		URL url = new URL(wsUrl);				URLConnection conn = url.openConnection();		HttpURLConnection con = (HttpURLConnection)conn;				con.setRequestMethod("GET");		int code = con.getResponseCode();		if(code == 200){			InputStream in = con.getInputStream();			byte[] b = new byte[1024];			int len = 0;			StringBuffer sb = new StringBuffer();			while((len=in.read(b))!=-1){				String s = new String(b,0,len,"UTF-8");				sb.append(s);			}			String json = sb.toString();			JSONObject o = JSONObject.fromObject(json);			Object obj = o.get("person");			json = obj.toString();					List
 list = (List
)JSONArray.toCollection(JSONArray.fromObject(json), Person.class); for(Person p:list){ System.out.println(p); } } con.disconnect(); }}

这是调用

----Person [desc=desc0, id=id0, name=person0]

Person [desc=desc2, id=id2, name=person2]

Person [desc=desc1, id=id1, name=person1]

Person [desc=desc0, id=id0, name=person0]

Person [desc=desc4, id=id4, name=person4]

Person [desc=desc3, id=id3, name=person3]

目前的webservice的就到这!

转载于:https://my.oschina.net/u/1425737/blog/217788

你可能感兴趣的文章
Office 2019 & Office 2016 下载地址
查看>>
tomcat应用转到weblogic上时的问题
查看>>
国外程序员是如何准备面试的
查看>>
Zookeeper监控之——node-zk-browser
查看>>
我的友情链接
查看>>
10个最酷的linux单行命令
查看>>
myeclipse 10 在mac retina 屏幕下显示字体模糊解决方法
查看>>
创建自定义的指令
查看>>
javascript对象中判断属性
查看>>
git删除分支与合并分支
查看>>
Python元组
查看>>
HD TUNE以及所有其他硬盘检测工具都不能使用的情况
查看>>
Linux内存分析
查看>>
vSphere 5.5 vCenter迁移至分布式交换机
查看>>
排序 遍历
查看>>
第二次作业
查看>>
Mysql主从复制
查看>>
高斯消元法解非奇异线性方程组的MATLAB程序
查看>>
Ubuntu下Tomcat连接MySql数据库
查看>>
WPF Summary 系列指导(连载中…^_^)
查看>>