以前在公司开发webservice,接触的都是axis1.4的版本,好久都没更新了。现在尝试一下使用CXF开发webservice来作为服务端,用axis来作为客户端来调用。
一、 新建个web工程,导入CXF 的一些JAR包,如果使用的JDK6的版本的话,只需要如下5个Jar包(不整合spring),若是JDK5.0,可以根据下载的apache-cxf-2.4.6下的lib文件夹下有WHICH_JARS文件,里面有对这些jar包的说明。(jdk5的另加上后面带[6]标志的jar包)
commons-logging-1.1.1.jar
cxf-2.4.6.jar
neethi-3.0.1.jar
wsdl4j-1.6.2.jar
xmlschema-core-2.0.1.jar
二、在src下建个包,如com.cxf.ws,再在此包下建个HelloWord类(建个接口也可以,不过这个简单例子就直接类实现了),最后增加以下方法,如:
- public String say(String text) {
- return "Hello World:" + text + "!";
- }
-
- public String[] says(String a1, String[] msgs) {
- String[] array = new String[msgs.length];
- for(int i=0; i<msgs.length; i++) {
- array[i] = a1 + "=>" + msgs[i];
- }
- return array;
- }
-
- public Long saveUser(User user) {
- if(null == user) {
- System.out.println("接收用户参数为NULL!");
- return null;
- }
- System.out.println("姓名:" + user.getUsername());
- return user.getId();
- }
public String say(String text) {
return "Hello World:" + text + "!";
}
public String[] says(String a1, String[] msgs) {
String[] array = new String[msgs.length];
for(int i=0; i<msgs.length; i++) {
array[i] = a1 + "=>" + msgs[i];
}
return array;
}
public Long saveUser(User user) {
if(null == user) {
System.out.println("接收用户参数为NULL!");
return null;
}
System.out.println("姓名:" + user.getUsername());
return user.getId();
}
注意:第三个方法需建一个User类,这个自己建个。
三、发布webservice,建个Servlet,如MyCXFServlet.java,由于采用了No Spring方式,需继承CXFNonSpringServlet,重写loadBus方法,实现如下:
- @Override
- protected void loadBus(ServletConfig config) {
- super.loadBus(config);
- ServerFactoryBean factory = new ServerFactoryBean();
- factory.setBus(getBus());
- factory.setServiceClass(HelloWorld.class);
- factory.setAddress("/hello");
- factory.getInInterceptors().add(new LoggingInInterceptor());
- factory.getOutInterceptors().add(new LoggingOutInterceptor());
- factory.create();
- }
@Override
protected void loadBus(ServletConfig config) {
super.loadBus(config);
ServerFactoryBean factory = new ServerFactoryBean();
factory.setBus(getBus());
factory.setServiceClass(HelloWorld.class);
factory.setAddress("/hello");
factory.getInInterceptors().add(new LoggingInInterceptor());
factory.getOutInterceptors().add(new LoggingOutInterceptor());
factory.create();
}
四,把这个Servlet加入Web.xml 中
- <servlet>
- <servlet-name>MyCXFServlet</servlet-name>
- <servlet-class>com.cxf.MyCXFServlet</servlet-class>
- </servlet>
-
- <servlet-mapping>
- <servlet-name>MyCXFServlet</servlet-name>
- <url-pattern>/ws/*</url-pattern>
- </servlet-mapping>
<servlet>
<servlet-name>MyCXFServlet</servlet-name>
<servlet-class>com.cxf.MyCXFServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>MyCXFServlet</servlet-name>
<url-pattern>/ws/*</url-pattern>
</servlet-mapping>
五、打开浏览器,输入http://localhost:8088/cxf/ws/hello?wsdl,能看到webservice正常发布。采用CXF能直接对一个pojo对象进行发布。
六、用axis1.4来作为客户端进行测试,新建个java项目,导入axis所需的jar包,
axis.jar
axis-ant.jar
commons-discovery-0.2.jar
commons-logging-1.0.4.jar
jaxrpc.jar
log4j-1.2.8.jar
saaj.jar
wsdl4j-1.5.1.jar
七、新建个测试类:测试代码如下:
- static void testSay() {
- Service service = new Service();
- try {
- Call call = (Call) service.createCall();
- call.setOperationStyle(Style.WRAPPED);
- call.setTargetEndpointAddress("http://localhost:8088/cxf/ws/hello");
- call.addParameter("text", XMLType.XSD_STRING, ParameterMode.IN);
- call.setReturnType(XMLType.XSD_STRING, String.class);
- String result = (String) call.invoke("say", new Object[]{"John"});
- System.out.println("结果:" + result);
- } catch (ServiceException e) {
- e.printStackTrace();
- } catch (RemoteException e) {
- e.printStackTrace();
- }
- }
-
- static void testSayArray() {
- Service service = new Service();
- try {
- Call call = (Call) service.createCall();
- call.setOperationStyle(Style.WRAPPED);
- call.setTargetEndpointAddress("http://localhost:8088/cxf/ws/hello");
- call.addParameter("a1", XMLType.XSD_STRING, ParameterMode.IN);
- call.addParameter("msgs", XMLType.XSD_STRING, String[].class, ParameterMode.IN);
- call.setReturnType(XMLType.XSD_STRING, String[].class);
- String a1 = "你好";
- String[] msgs = {"李四","张三","John"};
- String[] result = (String[]) call.invoke("says", new Object[]{a1, msgs});
- System.out.println("结果:");
- for(String r : result) {
- System.out.println(r);
- }
- } catch (ServiceException e) {
- e.printStackTrace();
- } catch (RemoteException e) {
- e.printStackTrace();
- }
- }
-
- public static void main(String[] args) {
- testSay();
- testSayArray();
- }
static void testSay() {
Service service = new Service();
try {
Call call = (Call) service.createCall();
call.setOperationStyle(Style.WRAPPED);
call.setTargetEndpointAddress("http://localhost:8088/cxf/ws/hello");
call.addParameter("text", XMLType.XSD_STRING, ParameterMode.IN);
call.setReturnType(XMLType.XSD_STRING, String.class);
String result = (String) call.invoke("say", new Object[]{"John"});
System.out.println("结果:" + result);
} catch (ServiceException e) {
e.printStackTrace();
} catch (RemoteException e) {
e.printStackTrace();
}
}
static void testSayArray() {
Service service = new Service();
try {
Call call = (Call) service.createCall();
call.setOperationStyle(Style.WRAPPED);
call.setTargetEndpointAddress("http://localhost:8088/cxf/ws/hello");
call.addParameter("a1", XMLType.XSD_STRING, ParameterMode.IN);
call.addParameter("msgs", XMLType.XSD_STRING, String[].class, ParameterMode.IN);
call.setReturnType(XMLType.XSD_STRING, String[].class);
String a1 = "你好";
String[] msgs = {"李四","张三","John"};
String[] result = (String[]) call.invoke("says", new Object[]{a1, msgs});
System.out.println("结果:");
for(String r : result) {
System.out.println(r);
}
} catch (ServiceException e) {
e.printStackTrace();
} catch (RemoteException e) {
e.printStackTrace();
}
}
public static void main(String[] args) {
testSay();
testSayArray();
}
注意:采用axis访问CXF发布的webservice,首先要设置Style的方式,如
call.setOperationStyle(Style.WRAPPED);这个是最关键的,没有这行代码是运行不成功的,其次要对每个参数的类型进行描述,没有直接用axis发布的webservice方便,毕竟是2个不同的webservice的实现方法。
问题:如果用cxf发布的webservice的方法中参数含有二维数组,如String[][] msgs,这个时候是可以正常发布的,但是不知道怎么用axis来设置参数调用?