webservice

WebService (三)使用CXF框架開發webservice

1CXF框架概念介紹

Apache CXF 是一個開源的 Services 框架,CXF 幫助您來構建和開發 Services 這些 Services 可以支持多種協議,比如:SOAPPOST/HTTPRESTful HTTP CXF 大大簡化了 Service可以天然地和 Spring 進行無縫集成。

11ServerFactoryBean來發布web服務

服務類代碼如下:

// 註解是無效的

@WebService(name="Hello",targetNamespace="http://icast.cn")

public class HelloWorld {

public String sayHi(String name) {

return "hello---->" + name;

}

}

發佈類代碼如下:

public static void main(String[] args) {

// 發佈服務的類類似Endpoint

ServerFactoryBean serverFactoryBean=new ServerFactoryBean();

// 註冊服務器地址和端口

serverFactoryBean.setAddress("http://127.0.0.1:9999/hello");

// 註冊哪個類提供服務

serverFactoryBean.setServiceBean(new HelloWorld());

// 發佈一個cxf服務

serverFactoryBean.create();

// 一分鐘有服務終止

Thread.sleep(1 * 60 * 1000);

// 正常退出程序

System.exit(0);

}

ServerFactoryBean注意事項:

這種方式沒有添加webService註解,也就是說沒有註解也可以發佈webService服務,但是這種方式不是很規範,比如我們不可以通過註解的方式來修改WSDL的標籤信息, 

12JaxWsServerFactoryBean來發布web服務

1. JaxWsServerFactoryBeanServerFactoryBean的子類,也是功能擴展類。

2. 此類,必須要在被髮布爲服務的類上添加@WebService註解,如果不加註解,雖然不出錯,但也不會對外暴露任何方法。使用此類生成的wsdl文件更加規範

3. 更重要的是可以通過添加攔截器攔截請求.

客戶端代碼如下:

@WebService

public class HelloWorld {

public String sayHi(String name) {

return "hello---->" + name;

}

}

發佈類代碼如下:

public static void main(String[] args)throws Exception {

// 發佈服務的類類似Endpoint

JaxWsServerFactoryBean jaxWsServer=new JaxWsServerFactoryBean();

// 註冊服務器地址和端口

jaxWsServer.setAddress("http://127.0.0.1:9999/hello");

// 註冊哪個類提供服務

jaxWsServer.setServiceBean(new HelloWorld());

// 配置輸入輸出日誌攔截器

jaxWsServer.getInInterceptors().add(new LoggingInInterceptor());

jaxWsServer.getOutInterceptors().add(new LoggingOutInterceptor());

// 發佈一個cxf服務

jaxWsServer.create();

// 一分鐘有服務終止

Thread.sleep(1 * 60 * 1000);

// 正常退出程序

System.exit(0);

}

訪問:http://127.0.0.1:9999/hello?wsdl 控制檯第一次握手攔截器日誌如下:

----------------------------

ID: 1

Address: http://127.0.0.1:9999/hello?wsdl

Http-Method: GET

Content-Type: 

Headers: {Accept=[*/*], accept-encoding=[gzip, deflate], Accept-Language=[zh-CN], connection=[Keep-Alive], Content-Type=[null], Host=[127.0.0.1:9999], User-Agent=[Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 6.1; Trident/4.0; SLCC2; .NET CLR 2.0.50727; .NET CLR 3.5.30729; .NET CLR 3.0.30729; Media Center PC 6.0)]}

--------------------------------------

通過Java客戶端調用服務類

public static void main(String[] args) {

HelloWorldService helloWorldService=new HelloWorldService();

HelloWorld helloWorld=helloWorldService.getHelloWorldPort();

System.out.println(helloWorld.sayHi("test"));

}

攔截器日誌如下:

----------------------------

ID: 1

Address: http://127.0.0.1:9999/hello?wsdl

Http-Method: GET

Content-Type: text/xml

Headers: {Accept=[*/*], Cache-Control=[no-cache], connection=[keep-alive], content-type=[text/xml], Host=[127.0.0.1:9999], Pragma=[no-cache], User-Agent=[Apache CXF 2.4.2]}

--------------------------------------

2013-1-6 11:28:17 org.apache.cxf.interceptor.AbstractLoggingInterceptor log

信息: Inbound Message

----------------------------

ID: 2

Address: http://127.0.0.1:9999/hello

Encoding: UTF-8

Http-Method: POST

Content-Type: text/xml; charset=UTF-8

Headers: {Accept=[*/*], Cache-Control=[no-cache], connection=[keep-alive], Content-Length=[191], content-type=[text/xml; charset=UTF-8], Host=[127.0.0.1:9999], Pragma=[no-cache], SOAPAction=[""], User-Agent=[Apache CXF 2.4.2]}

Payload: <soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/"><soap:Body><ns2:sayHi xmlns:ns2="http://jaxws.cxf.g.itcast.cn/"><arg0>test</arg0></ns2:sayHi></soap:Body></soap:Envelope>

--------------------------------------

2013-1-6 11:28:17 org.apache.cxf.interceptor.AbstractLoggingInterceptor log

信息: Outbound Message

---------------------------

ID: 2

Encoding: UTF-8

Content-Type: text/xml

Headers: {}

Payload: <soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/"><soap:Body><ns2:sayHiResponse xmlns:ns2="http://jaxws.cxf.g.itcast.cn/"><return>hello---->test</return></ns2:sayHiResponse></soap:Body></soap:Envelope>

--------------------------------------

13CXFSpring集成發佈WebService

前面的服務發佈包括創建服務類都是硬編碼的方式.是否可以使用配置的方式來發布服務類呢答案是肯定的這就要同Spring集成了由於cxf的項目已經集成了Spring(自帶了Spring lib)所以CXF的服務都是在Spring的配置文件中完成的並且我們需要把項目發佈到tomcat,所以我們可以創建一個web項目

配置開發環境:

l 建立一個web項目

l 準備所有jar,CXF_HOME\lib項目下的所有jar,全部都拷貝新項目的lib目錄下.其中裏面已經包含了Sring3.0jar包  其中jetty 服務器的包可以不要.因爲我們要部署的tomcat服務器中了

l 在web.xml中配置cxf的核心servletCXFServlet

l 此配置文件的作用類 攔截/ws/*的所有請求 類似Struts2的過濾器 

<servlet>

<servlet-name>cxf</servlet-name>

<servlet-class>org.apache.cxf.transport.servlet.CXFServlet</servlet-class>

<load-on-startup>1</load-on-startup>

</servlet>

<servlet-mapping>

<servlet-name>cxf</servlet-name>

<url-pattern>/ws/*</url-pattern>

</servlet-mapping>

通過Spring配置文件發佈服務

<beans xmlns="http://www.springframework.org/schema/beans"

xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 

xmlns:context="http://www.springframework.org/schema/context"

xmlns:jaxws="http://cxf.apache.org/jaxws" 

xmlns:p="http://www.springframework.org/schema/p"

xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd

http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd

http://cxf.apache.org/core http://cxf.apache.org/schemas/core.xsd

http://cxf.apache.org/jaxws http://cxf.apache.org/schemas/jaxws.xsd">

<!-- 這樣配置自身的服務也可以使用 -->

<bean id="userImpl" class="cn.itcast.i.cxf.spring.ws.UserImpl" />

<!-- id:邏輯名  serviceClass=服務接口類  address:調用的路徑  http://localhost:8888/項目名/ws/hello?wsdl> -->

<jaxws:server id="userService" serviceClass="cn.itcast.i.cxf.spring.ws.IUser" address="/hello">

<jaxws:serviceBean>

<ref bean="userImpl" />

</jaxws:serviceBean>

<jaxws:inInterceptors>

<bean class="org.apache.cxf.interceptor.LoggingInInterceptor" />

</jaxws:inInterceptors>

<jaxws:outInterceptors>

<bean class="org.apache.cxf.interceptor.LoggingOutInterceptor" />

</jaxws:outInterceptors>

</jaxws:server>

</beans>

服務接口如下:

@WebService

public interface IUser {

public void saveUser(User user);

public User getUser(int uid);

}

服務類如下:

public class UserImpl implements IUser {

private List<User> users=new ArrayList<User>();

 

public User getUser(int uid) {

for(User temp:users){

if(temp.getUid()==uid){

return temp;

}

}

return null;

}

public void saveUser(User user) {

// TODO Auto-generated method stub

users.add(user);

}

}

實體類如下:

public class User {

private int uid;

private String uname;

public int getUid() {

return uid;

}

public void setUid(int uid) {

this.uid = uid;

}

public String getUname() {

return uname;

}

public void setUname(String uname) {

this.uname = uname;

}

}

通過JSP+Servlet調用本地服務:

Servletweb.xml中配置如下:

<servlet>

<servlet-name>cxf</servlet-name>

<servlet-class>org.apache.cxf.transport.servlet.CXFServlet</servlet-class>

<load-on-startup>1</load-on-startup>

</servlet>

<servlet>

<servlet-name>UserServlet</servlet-name>

<servlet-class>cn.itcast.i.cxf.servlet.UserServlet</servlet-clas>

</servlet>

Servlet核心代碼調用如下:

public void doPost(HttpServletRequest request, HttpServletResponse response)

throws ServletException, IOException {

User user = new User();

user.setUid(Integer.parseInt(request.getParameter("uid")));

user.setUname(request.getParameter("uname"));

userImpl.saveUser(user);

}

public void init() throws ServletException {

// Put your code here

WebApplicationContext springContext = WebApplicationContextUtils

.getWebApplicationContext(this.getServletContext());

userImpl = (IUser) springContext.getBean("userImpl");

WEB頁面調用代碼如下:

<form action="/day01/servlet/UserServlet" method="post">

     用戶編號:<input type="text" name="uid" /><br/>

     用戶名:<input type="text" name="uname" /><br/>

     <input type="submit" value="提交" />

 </form>

通過Java遠程調用訪問CXFSpring服務如下:

public static void main(String[] args) {

IUserService userService=new IUserService();

User user=new User();

user.setUid(1);

user.setUname("admin");

userService.getIUserPort().saveUser(user);

User temp=userService.getIUserPort().getUser(1);

System.out.println(temp.getUid() + "|" + temp.getUname());

}

通過ajax遠程調用訪問CXFSpring服務如下:

<body>

        <button οnclick="mobile()">cxf+Spring測試</button>

</body>

<script language="javascript">

// 1:創建XMLHTTP對象

var xhr=null;

function mobile(){

// 聲明在訪問的ws的地址

var url="http://localhost:8888/day01/ws/hello";

// 書寫要發送的XML文件,即 SOAP

var soap='<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/"><soap:Body>' +

'<ns2:getUser xmlns:ns2="http://ws.spring.cxf.i.itcast.cn/"><arg0>1</arg0></ns2:getUser></soap:Body></soap:Envelope>';

// 3:打開連接

xhr.open("POST",url,true);

xhr.setRequestHeader("Content-Type","text/xml; charset=utf-8");

xhr.setRequestHeader("Accept","*/*");

xhr.onreadystatechange=callBack;

xhr.send(soap);

}

function callBack(){

if(xhr.readyState==4){

var a=xhr.responseXML;

alert(xhr.responseXML.getElementsByTagName("uid")[0].text);

alert(xhr.responseXML.getElementsByTagName("uname")[0].text);

}

}

function init(){

xhr=new ActiveXObject("MSXML2.XMLHTTP.3.0");

}

init();

</script>

 

發佈了37 篇原創文章 · 獲贊 17 · 訪問量 1萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章