CXF+webservice+rest
- CXF介紹、安裝和配置
- CXF介紹
- CXF是一個開源的webservice框架,提供很多完善功能,可以實現快速開發
- CXF支援的協議:SOAP1.1/1.2,REST
- CXF支援資料格式:XML,JSON(僅在REST方式下支援)
- CXF的安裝和配置
- 下載地址
http://cxf.apache.org/download.html
- 包結構介紹
- 安裝和配置
- 第一步:安裝JDK,建議1.7
- 第二步:解壓apache-cxf-2.7.11.zip到指定目錄,建立CXF_HOME
- 第三步:把CXF_HOME加入到Path路徑下
- 第四步:測試,在cmd下加入wsdl2java –h
- 如果不想使用IDE(比如Eclipse),需要在環境變數下配置如下資訊
- CXF釋出SOAP協議的服務
- 需求
服務端:釋出服務,接收客戶端的城市名,返回天氣資料給客戶端
客戶端:傳送城市名給服務端,接收服務端的響應資訊,列印
-
- 實現
- 服務端
- 實現
開發步驟:
第一步:匯入Jar包
第二步:建立SEI介面,要加入@WebService
package cn.ws.cxf.server;
import javax.jws.WebService;
@WebService public interface WeatherInterface {
public String queryWeather(String cityName); }
|
第三步:建立SEI實現類
package cn.ws.cxf.server;
public class WeatherInterfaceImpl implements WeatherInterface {
@Override public String queryWeather(String cityName) { System.out.println("from client..."+cityName); if("北京".equals(cityName)){ return "冷且霾"; } else { return "暖且晴"; } }
}
|
第四步:釋出服務, JaxWsServerFactoryBean釋出,設定3個引數,1.服務介面;2.服務實現類;3.服務地址;
endpoint僅支援釋出實現類,JaxWsServerFactoryBean支援釋出介面。
package cn.ws.cxf.server;
import org.apache.cxf.jaxws.JaxWsServerFactoryBean;
public class WeatherServer {
public static void main(String[] args) { //JaxWsServerFactoryBean釋出服務 JaxWsServerFactoryBean jaxWsServerFactoryBean = new JaxWsServerFactoryBean(); //設定服務介面 jaxWsServerFactoryBean.setServiceClass(WeatherInterface.class); //設定服務實現類 jaxWsServerFactoryBean.setServiceBean(new WeatherInterfaceImpl()); //設定服務地址 jaxWsServerFactoryBean.setAddress("http://127.0.0.1:12345/weather"); //釋出 jaxWsServerFactoryBean.create(); } }
|
第五步:測試服務是否釋出成功,閱讀使用說明書,確定關鍵點
如果在CXF釋出的服務下,直接訪問服務地址,會如下異常
此時直接訪問使用說明書地址即可
-
-
-
- 釋出SOAP1.2的服務端
-
-
- 在介面上加入如下註解:
@BindingType(SOAPBinding.SOAP12HTTP_BINDING)
- 重新發布服務端
-
-
- 攔截器
-
-
- 原理:
- 攔截器可以攔截請求和響應
- 攔截器可以有多個
- 攔截器可以根據需要自定義
- 使用
- 攔截器必須加到服務端,在服務端釋出之前
- 獲取攔截器列表,將自己的攔截器加入列表中
-
-
- 客戶端
-
第一步:生成客戶端程式碼
- Wsdl2java命令是CXF提供的生成客戶端的工具,他和wsimport類似,可以根據WSDL生成客戶端程式碼
- Wsdl2java -h,檢視命令
- Wsdl2java常用引數:
-d,指定輸出目錄
-p,指定包名,如果不指定該引數,預設包名是WSDL的名稱空間的倒序
- Wsdl2java支援SOAP1.1和SOAP1.2
第二步:使用說明書,使用生成程式碼呼叫服務端
JaxWsProxyFactoryBean呼叫服務端,設定2個引數,1.設定服務介面;2.設定服務地址
package cn.cxf.client;
import org.apache.cxf.jaxws.JaxWsProxyFactoryBean;
import cn.cxf.weather.WeatherInterface;
public class WeatherClient {
public static void main(String[] args) { //JaxWsProxyFactoryBean呼叫服務端 JaxWsProxyFactoryBean jaxWsProxyFactoryBean = new JaxWsProxyFactoryBean(); //設定服務介面 jaxWsProxyFactoryBean.setServiceClass(WeatherInterface.class); //設定服務地址 jaxWsProxyFactoryBean.setAddress("http://127.0.0.1:12345/weather"); //獲取服務介面例項 WeatherInterface weatherInterface = jaxWsProxyFactoryBean.create(WeatherInterface.class); //呼叫查詢方法 String weather = weatherInterface.queryWeather("保定"); System.out.println(weather); } }
|
- CXF+Spring整合釋出SOAP協議的服務
- 服務端
開發步驟:
第一步:建立web專案(引入jar包)
第二步:建立SEI介面
第三步:建立SEI實現類
第四步:配置spring配置檔案,applicationContext.xml,用<jaxws:server標籤釋出服務,設定1.服務地址;2.設定服務介面;3設定服務實現類
<?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" xmlns:jaxrs="http://cxf.apache.org/jaxrs" xmlns:cxf="http://cxf.apache.org/core" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://cxf.apache.org/jaxrs http://cxf.apache.org/schemas/jaxrs.xsd http://cxf.apache.org/jaxws http://cxf.apache.org/schemas/jaxws.xsd http://cxf.apache.org/core http://cxf.apache.org/schemas/core.xsd"> <!-- <jaxws:server釋出SOAP協議的服務 ,對JaxWsServerFactoryBean類封裝--> <jaxws:server address="/weather" serviceClass="cn.ws.cxf.server.WeatherInterface"> <jaxws:serviceBean> <ref bean="weatherInterface"/> </jaxws:serviceBean> </jaxws:server> <!-- 配置服務實現類 --> <bean name="weatherInterface" class="cn.ws.cxf.server.WeatherInterfaceImpl"/> </beans> |
第五步:配置web.xml,配置spring配置檔案地址和載入的listener,配置CXF的servlet
<?xml version="1.0" encoding="UTF-8"?> <web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd" id="WebApp_ID" version="3.0"> <display-name>ws_2_cxf_spring_server</display-name>
<!-- 設定spring的環境 --> <context-param> <!--contextConfigLocation是不能修改的 --> <param-name>contextConfigLocation</param-name> <param-value>classpath:applicationContext.xml</param-value> </context-param> <listener> <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class> </listener>
<!-- 配置CXF的Servlet --> <servlet> <servlet-name>CXF</servlet-name> <servlet-class>org.apache.cxf.transport.servlet.CXFServlet</servlet-class> </servlet> <servlet-mapping> <servlet-name>CXF</servlet-name> <url-pattern>/ws/*</url-pattern> </servlet-mapping>
<welcome-file-list> <welcome-file>index.jsp</welcome-file> </welcome-file-list> </web-app> |
第六步:部署到tomcat下,啟動tomcat
第七步:測試服務,閱讀使用說明書
WSDL地址規則:http://ip:埠號/專案名稱/servlet攔截路徑/服務名稱?wsdl
-
-
- 攔截器配置
-
配置applicationContext.xml中。
-
-
- Endpoint標籤釋出服務
-
<jaxws:endpoint>標籤
package cn.ws.cxf.server;
import javax.jws.WebService;
@WebService public class HelloWorld { public String sayHello(String name){ return "hello,"+name; } } |
applicationContext.xml配置檔案資訊:
-
- 客戶端
開發步驟:
第一步:引入jar包
第二步:生成客戶端程式碼
第三步:配置spring配置檔案,applicationContent.xml
<?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" xmlns:jaxrs="http://cxf.apache.org/jaxrs" xmlns:cxf="http://cxf.apache.org/core" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://cxf.apache.org/jaxrs http://cxf.apache.org/schemas/jaxrs.xsd http://cxf.apache.org/jaxws http://cxf.apache.org/schemas/jaxws.xsd http://cxf.apache.org/core http://cxf.apache.org/schemas/core.xsd"> <!-- <jaxws:client實現客戶端 ,對JaxWsProxyFactoryBean類封裝--> <jaxws:client id="weatherClient" address="http://127.0.0.1:8080/ws_2_cxf_spring_server/ws/weather" serviceClass="cn.cxf.weather.WeatherInterface"/> </beans> |
第四步:從spring上下檔案獲取服務實現類
第五步:呼叫查詢方法,列印
package cn.cxf.client;
import org.springframework.context.ApplicationContext; import org.springframework.context.support.ClassPathXmlApplicationContext;
import cn.itcast.cxf.weather.WeatherInterface;
public class WeatherClient {
public static void main(String[] args) { //初始化spring的上下文 ApplicationContext context = new ClassPathXmlApplicationContext("classpath:applicationContext.xml"); WeatherInterface weatherInterface = (WeatherInterface) context.getBean("weatherClient"); String weather = weatherInterface.queryWeather("保定"); System.out.println(weather); } }
|
- CXF釋出REST的服務
- 什麼是REST
- 定義:REST就是一種程式設計風格,它可以精確定位網上資源(服務介面、方法、引數)
- REST支援資料格式:XML、JSON
- REST支援傳送方式:GET,POST
- 需求
- 第一個:查詢單個學生
- 第二個:查詢多個學生
- 實現
- 服務端
- 實現
開發步驟:
第一步:匯入jar包
第二步:建立學生pojo類,要加入@ XmlRootElement
package cn.ws.rest.pojo;
import java.util.Date; import javax.xml.bind.annotation.XmlRootElement;
@XmlRootElement(name="student")//@XmlRootElement可以實現物件和XML資料之間的轉換 public class Student {
private long id;
private String name;
private Date birthday;
此處省略get/set方法 }
|
第三步:建立SEI介面
package cn.ws.rest.server;
import java.util.List; import javax.jws.WebService; 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 cn.ws.rest.pojo.Student;
@WebService @Path("/student")//@Path("/student")就是將請求路徑中的“/student”對映到介面上 public interface StudentInterface {
//查詢單個學生 @GET//指定請求方式,如果服務端釋出的時候指定的是GET(POST),那麼客戶端訪問時必須使用GET(POST) @Produces(MediaType.APPLICATION_XML)//指定服務資料型別 @Path("/query/{id}")//@Path("/query/{id}")就是將“/query”對映到方法上,“{id}”對映到引數上,多個引數,以“/”隔開,放到“{}”中 public Student query(@PathParam("id")long id);
//查詢多個學生 @GET//指定請求方式,如果服務端釋出的時候指定的是GET(POST),那麼客戶端訪問時必須使用GET(POST) @Produces(MediaType.APPLICATION_XML)//指定服務資料型別 @Path("/queryList/{name}")//@Path("/queryList/{name}")就是將“/queryList”對映到方法上,“{name}”對映到引數上,多個引數,以“/”隔開,放到“{}”中 public List<Student> queryList(@PathParam("name")String name); }
|
第四步:建立SEI實現類
package cn.ws.rest.server;
import java.util.ArrayList; import java.util.Date; import java.util.List; import cn.itcast.ws.rest.pojo.Student;
public class StudentInterfaceImpl implements StudentInterface {
@Override public Student query(long id) { Student st = new Student(); st.setId(110); st.setName("張三"); st.setBirthday(new Date()); return st; }
@Override public List<Student> queryList(String name) {
Student st = new Student(); st.setId(110); st.setName("張三"); st.setBirthday(new Date());
Student st2 = new Student(); st2.setId(120); st2.setName("李四"); st2.setBirthday(new Date());
List<Student> list = new ArrayList<Student>(); list.add(st); list.add(st2); return list; } } |
第五步:釋出服務, JAXRSServerFactoryBean釋出服務,3個引數,1:服務實現類;2.設定資源類;3.設定服務地址
package cn.ws.rest.server;
import org.apache.cxf.jaxrs.JAXRSServerFactoryBean;
public class StudentServer {
public static void main(String[] args) { //JAXRSServerFactoryBean釋出REST的服務 JAXRSServerFactoryBean jaxRSServerFactoryBean = new JAXRSServerFactoryBean();
//設定服務實現類 jaxRSServerFactoryBean.setServiceBean(new StudentInterfaceImpl()); //設定資源類,如果有多個資源類,可以以“,”隔開。 jaxRSServerFactoryBean.setResourceClasses(StudentInterfaceImpl.class); //設定服務地址 jaxRSServerFactoryBean.setAddress("http://127.0.0.1:12345/user"); //釋出服務 jaxRSServerFactoryBean.create(); } }
|
第六步:測試服務
http://127.0.0.1:12345/user/student/query/110 查詢單個學生,返回XML資料
<student> <birthday>2015-11-27T15:22:14.240+08:00</birthday> <id>110</id> <name>張三</name> </student> |
http://127.0.0.1:12345/user/student/queryList/110?_type=json 查詢多個學生,返回JSON
{"student":[{"birthday":"2015-11-27T15:24:21.565+08:00","id":110,"name":"張三"},{"birthday":"2015-11-27T15:24:21.565+08:00","id":120,"name":"李四"}]}
|
http://127.0.0.1:12345/user/student/queryList/110?_type=xml 查詢多個學生,返回XML
<students> <student> <birthday>2015-11-27T15:30:33.754+08:00</birthday> <id>110</id> <name>張三</name> </student> <student> <birthday>2015-11-27T15:30:33.754+08:00</birthday> <id>120</id> <name>李四</name> </student> </students> |
如果服務端釋出時指定請求方式是GET(POST),客戶端必須使用GET(POST)訪問服務端,否則會報如下異常
如果在同一方法上同時指定XML和JSON媒體型別,在GET請求下,預設返回XML,在POST請求下,預設返回JSON。
但可以自主選擇返回型別:請求地址後新增?_type=json/xml
http://127.0.0.1:12345/user/student/query/110?_type=xml返回xml格式
http://127.0.0.1:12345/user/student/query/110?_type=json返回json格式
-
-
- 客戶端
-
可以自學一下httpclient
http://hc.apache.org/httpclient-3.x/
package cn.cxf.client;
import java.io.BufferedReader; import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; import java.io.OutputStream; import java.net.HttpURLConnection; import java.net.MalformedURLException; import java.net.URL;
public class HttpClient {
public static void main(String[] args) throws IOException { //第一步:建立服務地址,不是WSDL地址 URL url = new URL("http://127.0.0.1:12345/user/student/query/110"); //第二步:開啟一個通向服務地址的連線 HttpURLConnection connection = (HttpURLConnection) url.openConnection(); //第三步:設定引數 //3.1傳送方式設定:POST必須大寫 connection.setRequestMethod("POST"); //3.2設定資料格式:content-type //3.3設定輸入輸出,因為預設新建立的connection沒有讀寫許可權, connection.setDoInput(true);
//第五步:接收服務端響應,列印 int responseCode = connection.getResponseCode(); if(200 == responseCode){//表示服務端響應成功 InputStream is = connection.getInputStream(); InputStreamReader isr = new InputStreamReader(is); BufferedReader br = new BufferedReader(isr);
StringBuilder sb = new StringBuilder(); String temp = null; while(null != (temp = br.readLine())){ sb.append(temp); } System.out.println(sb.toString()); is.close(); isr.close(); br.close(); } }
} |
- CXF+Spring整合釋出REST的服務
- 服務端
開發步驟:
第一步:建立web專案(引入jar包)
第二步:建立POJO類
第三步:建立SEI介面
第四步:建立SEI實現類
第五步:配置Spring配置檔案,applicationContext.xml,<jaxrs:server,設定1.服務地址;2.服務實現類
<?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" xmlns:jaxrs="http://cxf.apache.org/jaxrs" xmlns:cxf="http://cxf.apache.org/core" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://cxf.apache.org/jaxrs http://cxf.apache.org/schemas/jaxrs.xsd http://cxf.apache.org/jaxws http://cxf.apache.org/schemas/jaxws.xsd http://cxf.apache.org/core http://cxf.apache.org/schemas/core.xsd"> <!-- <jaxrs:server釋出REST的服務 ,對JAXRSServerFactoryBean類封裝--> <jaxrs:server address="/user"> <jaxrs:serviceBeans> <ref bean="studentInterface"/> </jaxrs:serviceBeans> </jaxrs:server>
<!-- 配置服務實現類 --> <bean name="studentInterface" class="cn.ws.rest.server.StudentInterfaceImpl"/> </beans> |
第六步:配置web.xml
<?xml version="1.0" encoding="UTF-8"?> <web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd" id="WebApp_ID" version="3.0"> <display-name>ws_2_cxf_spring_server</display-name>
<!-- 設定spring的環境 --> <context-param> <!--contextConfigLocation是不能修改的 --> <param-name>contextConfigLocation</param-name> <param-value>classpath:applicationContext.xml</param-value> </context-param> <listener> <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class> </listener>
<!-- 配置CXF的Servlet --> <servlet> <servlet-name>CXF</servlet-name> <servlet-class>org.apache.cxf.transport.servlet.CXFServlet</servlet-class> </servlet> <servlet-mapping> <servlet-name>CXF</servlet-name> <url-pattern>/ws/*</url-pattern> </servlet-mapping>
<welcome-file-list> <welcome-file>index.jsp</welcome-file> </welcome-file-list> </web-app> |
第七步:部署到tomcat下,啟動tomcat
第八步:測試服務
REST服務的使用說明書地址:
http://127.0.0.1:8080/ws_4_cxf_rest_spring_server/ws/user?_wadl
-
- 客戶端
<!doctype html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Document</title> <script type="text/javascript"> function queryStudent(){ //建立XMLHttpRequest物件 var xhr = new XMLHttpRequest(); //開啟連線 xhr.open("get","http://127.0.0.1:8080/ws_4_cxf_rest_spring_server/ws/user/student/queryList/110?_type=json",true); //設定回撥函式 xhr.onreadystatechange=function(){ //判斷是否傳送成功和判斷服務端是否響應成功 if(4 == xhr.readyState && 200 == xhr.status){ alert(eval("("+xhr.responseText+")").student[0].name); } } //傳送資料 xhr.send(null); } </script> </head> <body> <input type="button" value="查詢" onclick="javascript:queryStudent();"/> </body> </html> |
- 綜合案例
- 需求:
- 整合公網手機號歸屬地查詢服務
- 對外發布自己的手機號歸屬地查詢服務
- 提供查詢介面
- 分析
-
- 實現
開發步驟:
第一步:建立web專案(引入jar包)
第二步:生成公網客戶端程式碼
第三步:建立SEI介面
package cn.mobile.server;
import javax.jws.WebService;
@WebService public interface MobileInterface {
public |