我的第一次WebService介面開發教程
阿新 • • 發佈:2021-08-07
一、前言:
工作中,接觸到很多系統要互相對接,因為大多數公司(專案)所用的平臺不同,要想一方提供資料資訊供對方提取,首先想到的就是開放出一個WebService介面呼叫文件和WebService地址,這樣對方就能根據文件地址程式設計去呼叫。於是便在網上搜羅相關資料,嘗試寫一個WebService介面,非科班出身,僅供大家參考、指教。
二、WebService優點:
- 可遠端呼叫(WebService可以向全世界提供資訊,或提供某項功能,只要有網就OK)。
- 跨平臺呼叫(WebService可以在Windows上呼叫linux上的WebService服務,反之同理)。
- 跨語言呼叫(WebService可以在Java語言中呼叫asp.net語言提供的WebService服務,反之其他程式語言同理)
- ......
三、詳細開發步驟:
1)使用JDK開發WebService
WebService服務端
1.1首先我們先建立一個java專案,目錄及Util工具類和所應用的包:
這裡我用的是 C3p0 JDBC連線池方式我給大家提供MySql和oracle工具類,程式碼如下:
MySql:
package Util; import java.sql.Connection; import java.sql.ResultSet; import java.sql.SQLException; import java.sql.Statement; import javax.sql.DataSource;import com.mchange.v2.c3p0.ComboPooledDataSource; public class JDBCUtil2 { static ComboPooledDataSource dataSource = null; static{ dataSource = new ComboPooledDataSource(); } public static DataSource getDataSource(){ return dataSource; } /** * 獲取連線物件 *@return * @throws SQLException */ public static Connection getConn() throws SQLException{ return dataSource.getConnection(); } /** * 釋放資源 * @param conn * @param st * @param rs */ public static void release(Connection conn , Statement st , ResultSet rs){ closeRs(rs); closeSt(st); closeConn(conn); } public static void release(Connection conn , Statement st){ closeSt(st); closeConn(conn); } private static void closeRs(ResultSet rs){ try { if(rs != null){ rs.close(); } } catch (SQLException e) { e.printStackTrace(); }finally{ rs = null; } } private static void closeSt(Statement st){ try { if(st != null){ st.close(); } } catch (SQLException e) { e.printStackTrace(); }finally{ st = null; } } private static void closeConn(Connection conn){ try { if(conn != null){ conn.close(); } } catch (SQLException e) { e.printStackTrace(); }finally{ conn = null; } } public static void main(String[] args) throws Exception{ System.out.println(getConn()); System.out.println("---------------------------南清風工具類測試-------------------------------"); System.out.println("+++++++++++++++++++MySql Connection Successful!+++++++++++++++++++++"); System.out.println("---------------------------------------------------------------------"); } }
Oracle:
package Util; import java.sql.Connection; import java.sql.ResultSet; import java.sql.SQLException; import java.sql.Statement; import javax.sql.DataSource; import com.mchange.v2.c3p0.ComboPooledDataSource; public class JDBCUtil { private static ComboPooledDataSource ds = new ComboPooledDataSource(); private static ThreadLocal<Connection> tl=new ThreadLocal<>(); /** * 從執行緒中獲取連線 * @return * @throws SQLException */ public static Connection getConnection() throws SQLException { //從執行緒中獲取conneciton Connection conn = tl.get(); if(conn==null){ conn=ds.getConnection(); //和當前執行緒繫結 tl.set(conn); } return conn; } // 獲取資料來源 public static DataSource getDataSource() { return ds; } // 釋放資源 public static void closeResource( Statement st, ResultSet rs) { closeResultSet(rs); closeStatement(st); } // 釋放資源 public static void closeResource(Connection conn, Statement st, ResultSet rs) { closeResource(st, rs); closeConn(conn); } // 釋放 connection public static void closeConn(Connection conn) { if (conn != null) { try { conn.close(); //和執行緒解綁 tl.remove(); } catch (SQLException e) { e.printStackTrace(); } conn = null; } } // 釋放 statement ctrl + shift + f 格式化程式碼 public static void closeStatement(Statement st) { if (st != null) { try { st.close(); } catch (SQLException e) { e.printStackTrace(); } st = null; } } // 釋放結果集 public static void closeResultSet(ResultSet rs) { if (rs != null) { try { rs.close(); } catch (SQLException e) { e.printStackTrace(); } rs = null; } } //開啟事務 public static void startTransaction() throws SQLException{ getConnection().setAutoCommit(false); } /** * 事務提交且釋放連線 */ public static void commitAndClose(){ Connection conn = null; try { conn=getConnection(); //事務提交 conn.commit(); //關閉資源 conn.close(); //解除版定 tl.remove(); } catch (SQLException e) { e.printStackTrace(); } } /** * 事務回滾且釋放資源 */ public static void rollbackAndClose(){ Connection conn = null; try { conn=getConnection(); //事務回滾 conn.rollback(); //關閉資源 conn.close(); //解除版定 tl.remove(); } catch (SQLException e) { e.printStackTrace(); } } public static void main(String[] args) throws Exception{ System.out.println(getConnection()); System.out.println("---------------------------南清風工具類測試-------------------------------"); System.out.println("+++++++++++++++++++Oracle Connection Successful!+++++++++++++++++++++"); System.out.println("---------------------------------------------------------------------"); } }
1.2我們現在需要寫一個介面類、封裝物件類、實現類和攔截器,程式碼如下:
介面類:
package Dao; import java.sql.SQLException; import javax.jws.WebMethod; import javax.jws.WebParam; import javax.jws.WebService; @WebService public interface fwsyq { @WebMethod() String Get_fwsyq( @WebParam(name="cxtj",targetNamespace = "http://Dao.Get_fwsyq_impl.Get_fwsyq")String cxtj, @WebParam(name="cxnr",targetNamespace = "http://Dao.Get_fwsyq_impl.Get_fwsyq")String cxnr) throws SQLException; }
Bean封裝類:
package Bean; public class fwsyq_table2 { private int id; private String SLID; private String DJYY; private String DYH; private String QLR; private String BH; private String ZH; private float JZMJ; private String FDZL; private String XZ; private String DJSJ; private String djbzt; public fwsyq_table2() { super(); } public fwsyq_table2(int id, String sLID, String dJYY, String dYH, String qLR, String bH, String zH, float jZMJ, String fDZL, String xZ, String dJSJ, String djbzt) { this.id = id; SLID = sLID; DJYY = dJYY; DYH = dYH; QLR = qLR; BH = bH; ZH = zH; JZMJ = jZMJ; FDZL = fDZL; XZ = xZ; DJSJ = dJSJ; this.djbzt = djbzt; } public int getId() { return id; } public void setId(int id) { this.id = id; } public String getSLID() { return SLID; } public void setSLID(String sLID) { SLID = sLID; } public String getDJYY() { return DJYY; } public void setDJYY(String dJYY) { DJYY = dJYY; } public String getDYH() { return DYH; } public void setDYH(String dYH) { DYH = dYH; } public String getQLR() { return QLR; } public void setQLR(String qLR) { QLR = qLR; } public String getBH() { return BH; } public void setBH(String bH) { BH = bH; } public String getZH() { return ZH; } public void setZH(String zH) { ZH = zH; } public float getJZMJ() { return JZMJ; } public void setJZMJ(float jZMJ) { JZMJ = jZMJ; } public String getFDZL() { return FDZL; } public void setFDZL(String fDZL) { FDZL = fDZL; } public String getXZ() { return XZ; } public void setXZ(String xZ) { XZ = xZ; } public String getDJSJ() { return DJSJ; } public void setDJSJ(String dJSJ) { DJSJ = dJSJ; } public String getDjbzt() { return djbzt; } public void setDjbzt(String djbzt) { this.djbzt = djbzt; } @Override public String toString() { return "fwsyq_table2 [id=" + id + ", SLID=" + SLID + ", DJYY=" + DJYY + ", DYH=" + DYH + ", QLR=" + QLR + ", BH=" + BH + ", ZH=" + ZH + ", JZMJ=" + JZMJ + ", FDZL=" + FDZL + ", XZ=" + XZ + ", DJSJ=" + DJSJ + ", djbzt=" + djbzt + "]"; } }
介面實現類:
package Dao; import java.util.List; import org.apache.commons.dbutils.QueryRunner; import org.apache.commons.dbutils.handlers.BeanListHandler; import org.apache.commons.dbutils.handlers.ScalarHandler; import Bean.fwsyq_table; import Util.JDBCUtil2; import net.sf.json.JSONArray; public class Get_fwsyq_impl implements fwsyq { @Override public String Get_fwsyq(String cxtj, String cxnr) { try { QueryRunner qr = new QueryRunner(JDBCUtil2.getDataSource());if(cxtj!=null && cxnr!=null){ String sql="select id,slid,djyy,dyh,qlr,bh,zh,jzmj,fdzl,xz,djsj,djbzt from bqh_fq1 where "+cxtj+"="+"'"+cxnr+"'" +"order by id"; String sql1="select count(*) from bqh_fq1 where "+cxtj+"="+"'"+cxnr+"'"; List<fwsyq_table> data = qr.query(sql, new BeanListHandler<fwsyq_table>(fwsyq_table.class)); Long total=(Long) qr.query(sql1, new ScalarHandler()); //統計查詢總數 System.out.println("來自客戶端介面訪問:查詢成功!"); int count=total.intValue(); int code=0; String msg="\"查詢成功\""; String json1="{\"code\":"+code+",\"msg\":"+msg+",\"count\":"+count+",\"data\":"+JSONArray.fromObject(data).toString()+"}"; System.out.println(json1); return json1; }else { List<fwsyq_table> data =null; System.out.println("來自客戶端介面訪問:查詢失敗!"); int code=4; int count=0; String msg="\"查詢失敗\""; String json1="{\"code\":"+code+",\"msg\":"+msg+",\"count\":"+count+",\"data\":"+JSONArray.fromObject(data).toString()+"}"; return json1; } } catch (Exception e) { e.printStackTrace(); } return null; } }
1.3使用Endpoint類釋出WebService
package Publish_interface; import javax.xml.ws.Endpoint; import Dao.Get_fwsyq_impl; public class Get_FWSYQ { public static void main(String[] args){ //釋出介面地址 String address="http://192.168.0.188:9999/BDBDCDJ/Get_fwsyq"; //jdk方法實現 Endpoint.publish(address, new Get_fwsyq_impl()); System.out.println("Published successfully!"); } }
1.4啟動main方法執行這個類,打印出結果Published successfully,表示服務釋出成功:
1.5開啟瀏覽器,訪問我們釋出的地址(注意後面得加?wsdl),大家可以看到這樣的效果:
WSDL結構描述:
1.6我們可以用SoaoUI工具來測試一下介面:
OK,這樣一個簡單的WebService介面就OK了。
2)使用CXF開發WebService
cxf是java開發webService的一種實現框架技術。目前,cxf是主流的webService實現框架。
2.1使用cxf開發需引入cxf開發jar包
Jetty是一個內嵌的web伺服器,使用JaxWsServerFactoryBean類建立工廠設定介面地址、介面類、介面實現類,建立即可釋出。所以我們得引入jetty包,作為WebService釋出的Server。
2.2增加一個攔截器:
package Interceptor; import java.util.List; import org.apache.cxf.binding.soap.SoapMessage; import org.apache.cxf.interceptor.Fault; import org.apache.cxf.phase.AbstractPhaseInterceptor; import org.apache.cxf.phase.Phase; public class MyInterceptor extends AbstractPhaseInterceptor<SoapMessage>{ public MyInterceptor(){ // 在呼叫方法之前呼叫攔截器 super(Phase.PRE_INVOKE); } /** * 攔截獲取訊息 */ public void handleMessage(SoapMessage message) throws Fault { Object obj = message.getContent(List.class).get(0); System.out.println("引數1:"+obj); Object obj1 = message.getContent(List.class).get(1); System.out.println("引數2:"+obj1); if(!obj.equals("slid") || obj1==null){ throw new Fault(new IllegalArgumentException("引數1錯誤,請求失敗")); } if(obj1==null || obj1.equals("")){ throw new Fault(new IllegalArgumentException("引數2為空,請求失敗")); } } }
2.3使用jaws釋出WebService
package Publish_interface; import org.apache.cxf.interceptor.LoggingInInterceptor; import org.apache.cxf.interceptor.LoggingOutInterceptor; import org.apache.cxf.jaxws.JaxWsServerFactoryBean; import Dao.Get_fwsyq_impl; import Dao.fwsyq; import Interceptor.MyInterceptor; public class CXF_Get_FWSYQ { public static void main(String[] args) { //1.使用jaws釋出webservice JaxWsServerFactoryBean jsfb=new JaxWsServerFactoryBean(); //2.設定釋出服務的地址 jsfb.setAddress("http://192.168.0.188:9999/BDBDCDJ/Get_fwsyq"); //3.設定介面服務 jsfb.setServiceClass(fwsyq.class); //4.設定服務的實現物件 jsfb.setServiceBean(new Get_fwsyq_impl()); jsfb.getInInterceptors().add(new LoggingInInterceptor()); // 新增in攔截器 日誌攔截器 jsfb.getOutInterceptors().add(new LoggingOutInterceptor()); // 新增out攔截器 //新增自定義攔截器 jsfb.getInInterceptors().add(new MyInterceptor()); //5.通過工廠建立服務 jsfb.create(); System.out.println("Published successfully!"); } }
2.4啟動main方法執行這個類,打印出結果Cxfweb service published successfully,表示服務釋出成功:
2.5開啟瀏覽器,訪問我們釋出的地址(注意後面得加?wsdl),大家可以看到這樣的效果:
2.6我們可以用Postman工具來測試一下介面:
上邊驗證攔截器是否生效,下邊正常填寫引數,成功返回查詢結果:
四、客戶端呼叫介面:
3.1 新建一個客戶端java web專案
3.2java自帶wsimport命令生成webservice客戶端程式碼及服務呼叫
通過wsimport命令生成客戶端程式碼(通過cmd進入到當前專案的src路徑下,wsimport.exe命令在jdk的bin目錄下)
- 第一種方式【遠端地址】wsimport -s . 介面地址(加?wsdl)
- 第二種方式【xml檔案】wsimport -s . 檔案路徑(檔案路徑後面不需要加?wsdl)
wsimport -s . http://192.168.0.188:9999/BDBDCDJ/Get_fwsyq?wsdl
我們在看一下客戶端專案:重新整理一下如下:
3.3新建一個測試類,呼叫一下介面方法:
package Test_client; import dao.Fwsyq; import dao.FwsyqService; public class Test_class { public static void main(String[] args) throws Exception { //構建服務檢視物件(從service標籤name屬性獲取) FwsyqService service=new FwsyqService(); //獲取服務的實現類(從portType的name屬性獲取 Fwsyq prot=service.getPort(Fwsyq.class); //呼叫方法(portType下的operation屬性獲取 String info=prot.getFwsyq("slid", "202106070001"); System.out.println("呼叫服務端介面方法結果是:"+info); } }
3.4執行測試類結果如下:
Client console:
server console::
OK!一個基本的介面開發過程到此結束。
參考地址: