利用CXF釋出webService的小demo
其實webService的釋出不僅僅只有xfire,今天,給大家介紹一下用CXF釋出一個webService的小demo,CXF也是我做webService用的第一個框架。。。
先將相關的jar引進來,在pom檔案中新增
<dependency>
<groupId>org.apache.cxf</groupId>
<artifactId>cxf-rt-transports-http</artifactId>
<version>2.7.3</version>
</dependency>
<dependency>
<groupId>org.apache.cxf</groupId>
<artifactId>cxf-rt-frontend-jaxws</artifactId>
<version>2.7.3</version>
</dependency>
即可引入相關的
第一步,不廢話,還是寫一個簡單的介面與實現類,程式碼如下
public interface SayCXFService {
public String sayHello(String name);
}
public class SayCXFServiceImpl implements SayCXFService{
@Override
public String sayHello(String name) {
return name +" hello,this is my first CXF webService!";
}
}
接下來就是重點了,配置檔案了,配置檔案如下。相應的解釋也有
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="
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-3.0.xsd
http://cxf.apache.org/jaxws
default-lazy-init="true"
>
<!-- cxf 相關配置,這個照搬就行了,cxf框架裡面自帶的配置 -->
<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" />
<!-- service定義 -->
<bean id="sayCXFbean"
class="com.mip.biz.webservice.cxf.server.service.impl.SayCXFServiceImpl"
scope="singleton"
/>
<!--
serviceClass 表示你要對外開發的介面,address表示的地址,本質就是一個servletName,可以隨便命名
-->
<jaxws:server id="webService" serviceClass="com.mip.biz.webservice.cxf.server.service.SayCXFService" address="/server">
<!-- 表示你的介面實現類的bean -->
<jaxws:serviceBean>
<ref bean="sayCXFbean"/>
</jaxws:serviceBean>
</jaxws:server>
</beans>
然後是web.xml檔案新增如下內容
<servlet>
<description>apache cxf 配置 webservice 服務</description>
<servlet-name>CXFService</servlet-name>
<servlet-class>org.apache.cxf.transport.servlet.CXFServlet</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>CXFService</servlet-name>
<url-pattern>/CXFService/*</url-pattern>
</servlet-mapping>
除了測試類,似乎和前段時間的xfire沒啥區別,試一下啟動tomcat,會發現抱NullPointerException
org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'webService': Invocation of init method failed; nested exception is java.lang.NullPointerException
別急,你只需要在介面上稍微改動一下即可
//註解的方式,將介面注入,targetNamespace中的內容其實就是將包名寫反就行了。。這也是我們平時包名的命名規則類似。com開頭,然後模組名稱..有麼像www.ho123.com?
@WebService(targetNamespace = "http://service.server.cxf.webservice.biz.mip.com/")
public interface SayCXFService {
public String sayHello(String name);
}
//實現類
@WebService(endpointInterface="com.mip.biz.webservice.cxf.server.service.SayCXFService",
targetNamespace = "http://service.server.cxf.webservice.biz.mip.com/")
public class SayCXFServiceImpl implements SayCXFService{
@Override
public String sayHello(String name) {
return name +" hello,this is my first CXF webService!";
}
}
好了重啟不會報錯了
然後在瀏覽器中輸入http://localhost:8080/mip/CXFService/server?wsdl出現祖國江山一片紅的景象就ok了
-
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"
xmlns:tns="http://service.server.cxf.webservice.biz.mip.com/" elementFormDefault="unqualified"
targetNamespace="http://service.server.cxf.webservice.biz.mip.com/" version="1.0">
<xs:element
name="sayHello" type="tns:sayHello"
/>
<xs:element
name="sayHelloResponse" type="tns:sayHelloResponse"
/>
-
<xs:complexType name="sayHello">
+
<xs:sequence>
<xs:element minOccurs="0" name="arg0" type="xs:string" />
</xs:sequence>
</xs:complexType>
- 。。。。。。
注意到上面的紅色標記部分沒,其實我們可以將引數的名字顯示出來,改下介面
@WebService(targetNamespace = "http://service.server.cxf.webservice.biz.mip.com/")
public interface SayCXFService {
@WebMethod
@WebResult
//下面的name="wsdl中暴露出來的介面引數名稱"
public String sayHello(@WebParam(name="name",targetNamespace = "http://service.server.cxf.webservice.biz.mip.com/") String name);
}
重新看下wsdl檔案:
-
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"
xmlns:tns="http://service.server.cxf.webservice.biz.mip.com/" elementFormDefault="unqualified"
targetNamespace="http://service.server.cxf.webservice.biz.mip.com/" version="1.0">
<xs:element
name="sayHello" type="tns:sayHello"
/>
<xs:element
name="sayHelloResponse" type="tns:sayHelloResponse"
/>
-
<xs:complexType name="sayHello">
-
<xs:sequence>
<xs:element form="qualified" minOccurs="0" name="name" type="xs:string"
/>
</xs:sequence>
</xs:complexType>
-
以上是用java開發的服務端,下一章我們接著寫客戶端與測試類
@WebService(targetNamespace = "http://service.server.cxf.webservice.biz.mip.com/")
public interface SayCXFClient {
public String sayHello(String name); }
客戶端其實直接將服務端拷貝過來就可以了。。。。當然這是在java開發的服務端基礎上你才可以做,假如你的webservice服務端是其他語言開發的,,,那麼可以用其他方法生成客戶端咯,主要依據的是wsdl檔案。。這個我在下一篇部落格給大家介紹。。。請期待
最後在寫個測試類
public class Test {
public static void main(String[] args) {
JaxWsProxyFactoryBean factory = new JaxWsProxyFactoryBean();
factory.setServiceClass(SayCXFClient.class);
factory.setAddress("http://localhost:8080/mip/CXFService/server");
SayCXFClient service = (SayCXFClient) factory.create();
System.out.println(service.sayHello("zhouxy"));
}
}
執行輸出
Exception in thread "main" javax.xml.ws.soap.SOAPFaultException: Unmarshalling Error: unexpected element (uri:"", local:"arg0"). Expected elements are <{http://service.server.cxf.webservice.biz.mip.com/}name>
這個是由於我們在服務端明確指出了引數名name照成的,別擔心,改下就行了
@WebService(
targetNamespace = "http://service.server.cxf.webservice.biz.mip.com/")
public interface SayCXFClient {
@WebMethod
@WebResult
//下面的name="wsdl中暴露出來的介面引數名稱"
public String sayHello(@WebParam(name="name",targetNamespace = "http://service.server.cxf.webservice.biz.mip.com/") String name);
}
繼續執行輸出:
zhouxy hello,this is my first CXF webService!
ok,demo結束,更詳細的理論知識自己查資料去吧