cxf简单例子

时间:2021-03-16 19:49:27

cxf 这里介绍在web跟非web中的发布以及调用

准备条件:

1,导入cxf的相关jar包,以maven项目为例 pom的配置文件为

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>CXF</groupId>
<artifactId>CXF</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>war</packaging>
<name />
<description />
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
<dependencies>

<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>3.8.1</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.apache.cxf</groupId>
<artifactId>cxf-api</artifactId>
<version>2.5.0</version>
</dependency>
<dependency>
<groupId>org.apache.cxf</groupId>
<artifactId>cxf-rt-frontend-jaxws</artifactId>
<version>2.5.0</version>
</dependency>
<dependency>
<groupId>org.apache.cxf</groupId>
<artifactId>cxf-rt-bindings-soap</artifactId>
<version>2.5.0</version>
</dependency>
<dependency>
<groupId>org.apache.cxf</groupId>
<artifactId>cxf-rt-transports-http</artifactId>
<version>2.5.0</version>
</dependency>
<dependency>
<groupId>org.apache.cxf</groupId>
<artifactId>cxf-rt-transports-http-jetty</artifactId>
<version>2.5.0</version>
</dependency>
<dependency>
<groupId>org.apache.cxf</groupId>
<artifactId>cxf-rt-ws-security</artifactId>
<version>2.5.0</version>
</dependency>

<dependency>
<groupId>org.apache.openejb</groupId>
<artifactId>javaee-api</artifactId>
<version>5.0-1</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>jstl</artifactId>
<version>1.2</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>javax.servlet.jsp</groupId>
<artifactId>jsp-api</artifactId>
<version>2.1</version>
<scope>provided</scope>
</dependency>
</dependencies>
<build>
<finalName>CXF</finalName>
<plugins>
<plugin>
<artifactId>maven-war-plugin</artifactId>
</plugin>
<plugin>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<source>1.5</source>
<target>1.5</target>
</configuration>
</plugin>
</plugins>
</build>
</project>

2,创建实体类,接口以及实现类

 package pBean;

public class Reader {

private static final long serialVersionUID = 1L;

private String name;

private String password;

public Reader(){}

public Reader(String name,String password) {

this.name = name;

this.password = password;

}

public String getName() {

return name;

}

public void setName(String name) {

this.name = name;

}

public String getPassword() {

return password;

}

public void setPassword(String password) {

this.password = password;

}

//Get/Set方法省略

public String toString(){

return "Name:"+name+",Password:"+password;

}

}

定义接口类

package pInterface;

import java.util.List;

import javax.jws.WebParam;

import javax.jws.WebService;

import pBean.Reader;

@WebService

public interface IReaderService {

public Reader getReader(@WebParam(name = "name") String name,@WebParam(name = "password") String password);

public List<Reader> getReaders();

}

Tip:(里的WebParam必须指定,否则调用的时候返回null)

定义实现类

package pImpl;

import java.util.ArrayList;

import java.util.List;

import javax.jws.WebParam;

import pBean.Reader;

import pInterface.IReaderService;

public class ReaderService implements IReaderService{

public Reader getReader(@WebParam(name="name") String name,@WebParam(name="password") String password) {

return new Reader(name,password);

}

public List<Reader> getReaders(){

List<Reader> readerList = new ArrayList<Reader>();

readerList.add(new Reader("shun1","123"));

readerList.add(new Reader("shun2","123"));

return readerList;

}

}

目录结构

cxf简单例子

一、在非web中发布服务并调用

1,发布服务,

执行下面的main方法,这个服务就起来了,此时在浏览器输入http://localhost:8080/readerService?wsdl就能访问服务

package pTest;

import javax.xml.ws.Endpoint;

import pImpl.ReaderService;

/**

*@author chenrd

*@date 2018-3-20 下午3:55:42

*CXF自带了一个轻量的容器服务,相当于spring自己提供了IOC容器一样。

*我们可以先用它来测试一下我们部署成功没。

*/

public class Test {

public static void main(String[] args) {

System.out.println("Server is starting...");

ReaderService readerService = new ReaderService();

Endpoint.publish("http://localhost:8080/readerService",readerService);

System.out.println("Server is started...");

}

}

2,调用服务

package pTest;

import org.apache.cxf.jaxws.JaxWsProxyFactoryBean;

import pBean.Reader;

import pInterface.IReaderService;

/**

*@author chenrd

*@date 2018-3-20 下午4:35:14

*业务:

*部署成功后,我们就是要调用啦,

*它的调用也相当简单,跟xfire类似,取得接口,然后就可以跟本地类一样调用方法了。

*/

public class Test2 {

/**

* 这里很简单,也是取得一个工厂类,

* 然后直接设接口和地址再create就可以得取相应的接口了,

* 这里跟xfire一样,也是需要调用端先定义好接口原型,否则这些调用将无从说起。

*/

public static void main(String[] args) {

JaxWsProxyFactoryBean factoryBean = new JaxWsProxyFactoryBean();

factoryBean.setServiceClass(IReaderService.class);

factoryBean.setAddress("http://localhost:8080/readerService");

IReaderService readerService = (IReaderService)factoryBean.create();

Reader reader = readerService.getReader("shun","123");

System.out.println("Reader:"+reader);

}

}

二、在web中发布服务并调用

添加下面1和2的条件

1,在web.xml中添加

<!-- 这里很简单,只是指定了spring的监听器和相应的配置文件路径,并且指定了CXF的拦截方式。 -->
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>WEB-INF/beans.xml</param-value>
</context-param>

<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>

<servlet>
<servlet-name>CXFServlet</servlet-name>
<servlet-class>org.apache.cxf.transport.servlet.CXFServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>CXFServlet</servlet-name>
<url-pattern>/webservice/*</url-pattern>
</servlet-mapping>

2,spring配置文件中的配置(这里单独放到了一个文件)

<?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"
xsi:schemaLocation="
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://cxf.apache.org/jaxws
http://cxf.apache.org/schemas/jaxws.xsd">

<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" />

<jaxws:endpoint id="readerServicce2"  implementor="pImpl.ReaderService" address="/readerService2" />
</beans>

说明:

<!-- 
这里很简单,只是通过jaxws:endpoint定义了一个webservice,
implementor是webservice的处理类,而address是它的访问路径,跟我们前面写的readerService类似。
这时我们可以把它部署到tomcat中,通过http://localhost:8080/CXF/webservice/readerService2?wsdl可以直接访问。

有些朋友会问,为什么这次访问的URL跟前面的不一样呢。
其实前面的访问地址是我们自己定义的,而这里的webservice地址是我们在配置文件中配置好的,并且是通过web项目来部署的,
这里就需要用项目名称,而且我们在CXFServlet那里配置了url-pattern是webservice,
所以最后的URL就跟上面一致了。 -->

发布(部署你的项目到tomcat并跑起来)

调用:

package pTest;

import javax.xml.namespace.QName;

import org.apache.cxf.endpoint.Client;
import org.apache.cxf.jaxws.endpoint.dynamic.JaxWsDynamicClientFactory;

import pBean.Reader;

/**
* @author chenrd
* @date 2018-3-21 上午11:39:31 业务:
*/
public class Test3 {
public static void main(String[] args) {
//这个是用cxf 客户端访问cxf部署的webservice服务
//千万记住,访问cxf的webservice必须加上namespace ,否则通不过
//现在又另外一个问题,传递过去的参数服务端接收不到
JaxWsDynamicClientFactory dcf = JaxWsDynamicClientFactory.newInstance();
//url为调用webService的wsdl地址
Client client = dcf.createClient("http://localhost:8080/CXF/webservice/readerService2?wsdl");
//第一个参数是wsdl的命名空间
QName qname=new QName("http://pInterface/","getReader");
//namespace是命名空间,methodName是方法名
String name = "name";
String pwd = "pwd";
//paramvalue为参数值
Object[] objects = null;
Object object = null;
try {
object = client.invoke(qname,name,pwd);
} catch (Exception e) {
e.printStackTrace();
}
//调用web Service//输出调用结果
System.out.println(object);
// System.out.println(((Reader)objects[0]).toString());
}
}