WebService技術總結(三):專案實戰——使用XML,dom4j,Xpath實現遠端呼叫
阿新 • • 發佈:2019-01-07
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>
服務端程式碼:
- 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);
}
}
返回結果: