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?

wtf?网上百度了一下这错误,无果,然后翻墙谷歌,任然无果,尝试用APT命令编译,百度出来的教程惨不忍睹,最后在csdn的一篇博客中看到解决方法:http://blog.csdn.net/rongbo_j/article/details/50967438

解决方法如下:

1.打开cmd,进入到服务端项目bin路径下
2.执行以下命令:wsgen -keep -cp . com.yonyou.service.imp.InvoiceServiceImp
这里写图片描述
3.打开生成的ExceptionBean.java,全选,复制到src目录下
4.运行发布程序即可

至此,服务端代码编写完成,可以输入http://10.101.238.173:20161/invoice?wsdl看一下生成的wsdl文件
这里写图片描述


生成客户端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);
    }
}

返回结果:
这里写图片描述

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值