1. 程式人生 > >WebService技術總結(三):專案實戰——使用XML,dom4j,Xpath實現遠端呼叫

WebService技術總結(三):專案實戰——使用XML,dom4j,Xpath實現遠端呼叫

XML具有跨平臺性,在企業webservice開發中, 經常將請求引數封裝為XML,並且返回一個XML作為結果。

需求: 客戶端將發票號碼,發票程式碼作為條件,呼叫服務端,查詢金額,稅額資訊

客戶端請求引數xml形式:

<?xml version="1.1"  encoding="utf-8"?>
<invoice>
    <code>4200161130</code>
    <number>01140087</number>
</invoice>

服務端返回的XML結果:

<?xml version="1.0" encoding="UTF-8"?>
<result> <invoice> <amount precision="2">403.77</amount> <tax precision="2">24.23</tax> </invoice> </result>

服務端程式碼:

  1. POJO:Invoice
public class Invoice {
    private String code;
    private String num;
    private double amount;
    private
double tax; //省略getter和setter }

2.DAO實現類,省略DAO介面:使用oracle資料庫做了一個簡單的查詢操作,結果封裝為一個java bean集合

public class InvoiceDaoImp implements InvoiceDao {

    @Override
    public List<Invoice> query(String code, String num) throws Exception {
        String url = "jdbc:oracle:thin:@10.101.238.173:1521:orcl"
; String user = "gkzq"; String password = "gkzq"; Class.forName("oracle.jdbc.driver.OracleDriver"); Connection connection = DriverManager.getConnection(url, user, password); String sql = "SELECT account, tax FROM bd_invoice WHERE code = ? and name = ?"; PreparedStatement stat = connection.prepareStatement(sql); stat.setString(1, code); stat.setString(2,num); ResultSet results = stat.executeQuery(); List<Invoice> invoices = new ArrayList<Invoice>(); while(results.next()){ Invoice invoice = new Invoice(); double amount = results.getDouble(1); double tax = results.getDouble(2); invoice.setAmount(amount); invoice.setTax(tax); invoices.add(invoice); } return invoices; } }

3.webservice部分:SEI及其實現類

注意這裡丟擲了Exception異常,為後面的一個bug埋下伏筆

public interface InvoiceService {
    public String getInvoices(String clientXml) throws Exception;
}

實現類:涉及到了dom4j和Xpath的相關知識,十分簡單,都是見名知意的API,忘了的同學可以複習一下

  • 方法parseXml解析從客戶端傳來的請求XML,並封裝成一個Invoice物件;
  • 方法create將服務端查詢的List結果物件轉換為一個XML,返回給客戶端;
@WebService(targetNamespace="http://invoice.yonyou.com",
serviceName="InvoiceService",
name="InvoicePort")
@SOAPBinding(style = SOAPBinding.Style.RPC)
public class InvoiceServiceImp implements InvoiceService{
    private InvoiceDao invoiceDao = new InvoiceDaoImp(); 

    @Override
    @WebMethod
    public @WebResult(name="rspXml")String getInvoices(@WebParam(name="requestXml")String clientXml) throws Exception {
        //客戶端傳過來的是一個xml,條件都在xml裡
        Invoice condition = parseXml(clientXml);
        //查詢結果
        List<Invoice> invoices = invoiceDao.query(condition.getCode(), condition.getNum());
        //把結果也要轉換成一個xml,返回給客戶端
        return create(invoices);
    }

    private String create(List<Invoice> invoices) {
        Document rspXml = DocumentHelper.createDocument();
        Element root = DocumentHelper.createElement("result");
        rspXml.setRootElement(root);
        if(invoices != null && invoices.size() > 0){
            for (Invoice temp : invoices) {
                Element invoice = root.addElement("invoice");
                Element amount = invoice.addElement("amount");
                amount.addText(temp.getAmount() + "");
                amount.addAttribute("precision", "2");
                Element tax = invoice.addElement("tax");
                tax.addText(temp.getTax() + "");
                tax.addAttribute("precision", "2");
            }
        }
        return rspXml.asXML();
    }

    private Invoice parseXml(String clientInfo) throws Exception{
        Document doc = DocumentHelper.parseText(clientInfo);
        String code = doc.selectSingleNode("/invoice/code").getText();
        String num = doc.selectSingleNode("/invoice/number").getText();
        Invoice temp = new Invoice();
        temp.setCode(code);
        temp.setNum(num);
        return temp;
    }
}

服務端程式碼的編寫到此結束了,可以釋出服務了,編寫釋出服務的程式碼:

public class Publish {
    public static void main(String[] args) {
        String address = "http://10.101.238.173:20161/invoice";
        Endpoint.publish(address, new InvoiceServiceImp());
    }
}

執行結果如下:

com.sun.xml.internal.ws.model.RuntimeModelerException: runtime modeler error: Wrapper class com.yonyou.service.imp.jaxws.ExceptionBean is not found. Have you run APT to generate them?

解決方法如下:

1.開啟cmd,進入到服務端專案bin路徑下
2.執行以下命令:wsgen -keep -cp . com.yonyou.service.imp.InvoiceServiceImp
這裡寫圖片描述
3.開啟生成的ExceptionBean.java,全選,複製到src目錄下
4.執行釋出程式即可

生成客戶端java檔案

接下來都是很簡單的操作了

1.cmd切換到客戶端專案src下

2.執行wsdl2java命令:wsdl2java -d . -frontend jaxws21 http://10.101.238.173:201
61/invoice?wsdl

3.客戶端生成的程式碼如下:
這裡寫圖片描述

客戶端呼叫

首先準備請求的XML檔案

<?xml version="1.1"  encoding="utf-8"?>
<invoice>
    <code>4200161130</code>
    <number>01140087</number>
</invoice>

編寫呼叫的程式碼:

public class Client {
    public static String requestXml = "<?xml version=\"1.1\"  encoding=\"utf-8\"?>" +
            "<invoice>" +
            "<code>4200161130</code>" +
            "<number>01140087</number>" +
            "</invoice>";
    public static void main(String[] args) throws Exception_Exception, MalformedURLException {
        URL url = new URL("http://10.101.238.173:20161/invoice?wsdl");
        String namespace = "http://invoice.yonyou.com";
        String serviceName = "InvoiceService";
        QName qName = new QName(namespace, serviceName);
        Service service = Service.create(url,qName);
        InvoicePort port = service.getPort(InvoicePort.class);
        String rspXml = port.getInvoices(requestXml);
        System.out.println(rspXml);
    }
}

返回結果:
這裡寫圖片描述