利用jws釋出一個查詢員工資訊的Web服務(員工資訊儲存在資料庫中)

shuaishuai3409發表於2016-06-13

這是《基於服務的軟體系統》的課程設計:

一.作業要求

編寫查詢員工資訊的Web服務(員工資訊儲存在資料庫中)。第一個Web服務:輸入員工號,返回該員工號的員工的基本資訊,包括員工號、員工名稱、所在部門、出生日期、職位、職稱、入職日期等資訊。第二個Web服務:輸入部門、職稱,返回該部門具有該職稱的所有員工的基本資訊,員工基本資訊與上面相同。分別針對上述兩個Web服務,分別編寫呼叫這兩個Web服務的程式(或網頁)。要求在輸入介面上輸入待查詢資料,呼叫Web服務,並將Web服務返回的員工資訊查詢結果顯示到輸出介面上。


二.JAVA釋出Web服務的發展

目前自己只是簡單瞭解了下Axis、xfire、axis2、cxf、jws、jax-rs這6項技術,其中Axis是較老的框架,從ppt的文件中也可看出進行開發需要的配置過程會很繁瑣。Axis2是axis的升級版本,速度有顯著提高,記憶體佔用低,同時保留通過各種方式擴充套件功能的空間。Xfire和axis2地位相似,是新一代的web框架,但用XFire 進行WebService 的開發比Axis2 簡單很多。CXF 更注重開發人員的工效(ergonomics )和嵌入能力(embeddability )。大多數配置都可以API 來完成,替代了比較繁瑣的XML 配置檔案, 用Spring 的會比較常用cxf。JAX-WS規範是一組XML web services的JAVA API,JAX-WS是使用RPC模式 來實現自己的web services,而jax-rs是用表述性狀態轉移(REST)架構風格建立Web服務,不同於RPC,是一種新的遠端通訊架構。目前jws用的較多,應用所楊老師的一個系統用的就是jws框架。


三.查詢員工資訊的Web服務-JWS

3.1 資料庫設計

根據要求,設計員工資訊staff表。

屬性 資料型別
staffID 員工號 Int(4)
staffName 員工名 Varchar(20)
Department 部門 Varchar(20)
Title 職稱 Vachar(20)
Position 職位 Vachar(20)
Birth 出生日期 Datatime
Jionday 入職日期 Datatime

資料庫名稱為company,表的名稱為staff,表的內容:
這裡寫圖片描述


3.2 釋出Web服務以及客戶端遠端呼叫服務

JAVA JDK1.6中JAX-WS規範定義瞭如何釋出一個WebService服務。與Web服務相關的類都位於Javax.jws.*包中。其中:
@WebService——此註解用在類上指定將此類釋出成一個WebService。targetNamespace屬性定義了自己的名稱空間,serviceName則定義了< definitions >標籤和標籤的name屬性。
EndPoint——此類為端點服務類,其中publish()方法用於將一個已經新增了@WebService註解的Web服務(類)繫結到一個地址的埠上,用於釋出。
@WebMethod定義Web Service運作的方法。
@SOAPBinding標籤定義了WSDL文件中SOAP的訊息協議,其中style屬性對應SOAP的文件型別,可選的有RPC和DOCUMENT。

然後在客戶端,通過Service.getPort()方法提取服務埠,遠端呼叫服務中運作的方法。框架圖:
這裡寫圖片描述

由於兩個web服務功能相近,操作相似,不同點在於呼叫服務的引數不同。這裡詳細介紹根據員工ID號查詢員工基本資訊的服務。根據部門和職稱查詢員工資訊的服務會給出必要的截圖,並在附件中給出原始碼。
客戶端呼叫遠端服務流程圖:
這裡寫圖片描述

流程圖說明:
1)定義類sqlserverImpl,按要求實現查詢資料庫的服務,本地實現用於測試。
2)將類用@webservice註釋,標明將該類暴露為webservice,供遠端呼叫
3)用端點類Endpoint的publish()方法,定義好釋出服務的URL,指定釋出地址以及埠號,釋出web服務。
4)在瀏覽器輸入自己釋出的web服務wsdl地址,(http://localhost:10101/myweb?wsdl),如果顯示如圖4.4,說明服務釋出成功
這裡寫圖片描述
5)在客戶端建立service物件,通過getport()方法遠端訪問服務埠
6)呼叫遠端服務readsql(),在客戶端返回結果。

執行結果:輸入員工號1001,顯示如圖:
這裡寫圖片描述


四.分析總結
本次課程作業,對SBS中soap、wsdl、uddi有了深刻了解。掌握了java釋出web服務的幾種方式。總結如下:
1)SOAP,作為傳輸層,是Web services 的通訊協議。用來在消費者和服務提供者之間傳送訊息。SOAP是一種基於XML 的機制,用於在網路應用程式之間進行結構化資料交換。SOAP中會指定服務端呼叫的方法,已經呼叫的引數等。
2)WSDL用來描述服務。它是一個XML 文件,實現SOAP協議,把它寫成可供電腦識別的檔案,描述了web服務的三個屬性:(1)服務所提供的操作(2)如何訪問服務(3)服務位於何處(通過 URL 來確定)。
3)UDDI用來註冊和查詢服務。它就是一個目錄,只不過在這個目錄中存放的是一些關於 Web 服務的資訊而已,使用者可以在這個目錄中查詢服務,取得服務的WSDL描述,然後通過SOAP來呼叫服務(這個過程叫把web服務請求者和合適的web服務繫結)。

另外Java類若想釋出為Web Service需要注意以下幾點:這個類必須是public類;這些類不能是final的或者abstract;這個類必須有一個公共的預設建構函式;這個類不能有finalize()方法。

六.附件
6.1 服務一的程式碼:
程式碼1:介面

package myweb.service;
    import javax.jws.WebService;
    import javax.jws.WebMethod;
    import javax.jws.soap.SOAPBinding;
    import javax.jws.soap.SOAPBinding.Style;
    @WebService
    @SOAPBinding(style=Style.RPC)
    public interface SqlServer {
        @WebMethod
        void readSql(int ID);
    }

程式碼2:實現介面的類,重寫其中的方法。

package myweb.service;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.text.DateFormat;
import java.util.Date;
import java.util.Scanner;

import javax.jws.WebService;

/*
  @WebService - 它是一個註解,用在類上指定將此類釋出成一個ws. 
    Endpoint – 此類為端點服務類,它的方法publish用於將一個已經新增了@WebService註解物件繫結到一個地址的埠上。
    */
@WebService(endpointInterface = "myweb.service.SqlServer")
public class SqlServerImpl implements SqlServer {

    public String readSql(int ID){
        String url="jdbc:mysql://localhost:3306/company";
        String user="root";
        String password="";//沒有密碼
        String sqll="select * from staff where staffID=";
        //String staff="";
        //System.out.println("11");
        String fanhui="";
        try {
            Class.forName("org.mariadb.jdbc.Driver");
            Connection connection;
            connection = DriverManager.getConnection(url,user,password);
            System.out.println("資料庫連線成功");
            Statement statement =connection.createStatement();
            ResultSet result=statement.executeQuery(sqll+ID);

            while(result.next()){
                String staffID=result.getString("staffID");
                String staffName=result.getString("staffName");
                String department=result.getString("department");
                String title=result.getString("title");
                String position=result.getString("position");
                String birth=result.getString("birth");
                String joinDay=result.getString("joinDay");
                //staff=staffID+staffName;
                fanhui=staffID+"        "+staffName+"   "+department+"      "+title+"       "+position+"    "+" "+birth+"       "+joinDay;
                //System.out.println(staffID+"      "+staffName+"   "+department+"      "+title+"       "+position+"    "+" "+birth+"       "+joinDay);
            }
            if(result!=null){result.close();result=null;}
            if(statement!=null){statement.close();statement=null;}
            if(connection!=null){connection.close();connection=null;}


        } catch (ClassNotFoundException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
         catch (SQLException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
        return  fanhui;
    }

程式碼3:釋出服務

package myweb.service;
import javax.xml.ws.Endpoint;
public class SqlServerPublisher {
    public static void main(String[] args){
        // 第一個引數是釋出的URL
        // 第二個引數是服務的實現
        Endpoint.publish("http://127.0.0.1:10101/myweb", new SqlServerImpl());
    }
}

程式碼4:客戶端呼叫服務

package myweb.client;
import javax.xml.namespace.QName;
import javax.xml.ws.Service;
import java.net.URL;
import java.util.Scanner;

import myweb.service.*;

public class SqlClient {
    public static void main(String[] args) throws Exception{
        URL url = new URL("http://localhost:10103/myweb?wsdl");
        // 第一個引數是服務的URI
        // 第二個引數是在WSDL釋出的服務名
        QName qname = new QName("http://service.myweb/","SqlServerImplService");
        // 建立服務
        Service service = Service.create(url, qname);
        // 提取端點介面,服務“埠”。
        SqlServer eif = service.getPort(SqlServer.class);

        System.out.println("請輸入員工ID號:");
        Scanner scanner=new Scanner(System.in);
        int ID=scanner.nextInt();
        System.out.println("staffID  staffName    department    title    position    birth    joinDay");
        System.out.println(eif.readSql(ID));

    }
}

6.2 第二個服務-根據department和title查詢使用者title。

1) 服務端查詢資料庫程式碼及截圖:服務實現部分只有黃色加註不同於服務一,其餘相同。

package myweb.service;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.text.DateFormat;
import java.util.Date;
import java.util.Scanner;

import javax.jws.WebService;

/*
  @WebService - 它是一個註解,用在類上指定將此類釋出成一個ws. 
    Endpoint – 此類為端點服務類,它的方法publish用於將一個已經新增了@WebService註解物件繫結到一個地址的埠上。
    */
@WebService(endpointInterface = "myweb.service.SqlServer")
public class SqlServerImpl implements SqlServer {
public String readSql2(String depar, String tit){
        String url="jdbc:mysql://localhost:3306/company";
        String user="root";
        String password="";//沒有密碼
        String fanhui2="";
        try {
            Class.forName("org.mariadb.jdbc.Driver");
            Connection connection;
            connection = DriverManager.getConnection(url,user,password);
            System.out.println("資料庫連線成功");
            Statement statement =connection.createStatement();
            String temp = "select * from staff where department  = '"+depar+"' and title = '"+tit+"'";
            ResultSet result=statement.executeQuery(temp);

            while(result.next()){
                String staffID=result.getString("staffID");
                String staffName=result.getString("staffName");
                String department=result.getString("department");
                String title=result.getString("title");
                String position=result.getString("position");
                String birth=result.getString("birth");
                String joinDay=result.getString("joinDay");
                fanhui2=staffID+"       "+staffName+"   "+department+"      "+title+"       "+position+"    "+" "+birth+"       "+joinDay;
                //return fanhui2;
                //System.out.println(staffID+"      "+staffName+"   "+department+"      "+title+"       "+position+"    "+" "+birth+"       "+joinDay);
            }
            if(result!=null){result.close();result=null;}
            if(statement!=null){statement.close();statement=null;}
            if(connection!=null){connection.close();connection=null;}


        } catch (ClassNotFoundException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
         catch (SQLException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
        return fanhui2;
    }

}

這裡寫圖片描述

2) 釋出服務,埠號從新選擇為10103:

package myweb.service;
import javax.xml.ws.Endpoint;
public class SqlServerPublisher {
    public static void main(String[] args){
        // 第一個引數是釋出的URL
        // 第二個引數是SIB實現,10103是服務繫結的地址埠號。
        Endpoint.publish("http://127.0.0.1:10103/myweb", new SqlServerImpl());
    }
}

3) 服務二的wsdl截圖如下:
這裡寫圖片描述
4)客戶端程式碼:

package myweb.client;
import javax.xml.namespace.QName;
import javax.xml.ws.Service;
import java.net.URL;
import java.util.Scanner;

import myweb.service.*;

public class SqlClient {
    public static void main(String[] args) throws Exception{
        URL url = new URL("http://localhost:10103/myweb?wsdl");
        // 第一個引數是服務的URI
        // 第二個引數是在WSDL釋出的服務名
        QName qname = new QName("http://service.myweb/","SqlServerImplService");
        // 建立服務
        Service service = Service.create(url, qname);
        // 提取端點介面,服務“埠”。
        SqlServer eif = service.getPort(SqlServer.class);

        System.out.println("請輸入員工department:");
        Scanner scanner=new Scanner(System.in);
        String depart=scanner.nextLine();
        System.out.println("請輸入員工title:");
        String tit=scanner.nextLine();
        System.out.println("staffID  staffName    department    title    position    birth    joinDay");
        //System.out.println(eif.readSql(ID));
        //Scanner scanner=new Scanner(System.in);
        //String dep=scanner.nextLine();
        //String tit=scanner.nextLine();
        System.out.println(eif.readSql2(depart, tit));
    }
}

相關文章