历史版本2 :WebService程序数据集 返回文档
编辑时间: 内容长度:图片数:目录数: 修改原因:

 

目录:

WebService程序数据集之jws方式编辑

1. 示例
 
1.1 WebService应用服务
如在Tomcat下的Axis工程中以jws方式发布了一个WebService应用服务TestWS2TDClient.jws,返回一个数组数据。如下:
  1. public class TestWS2TDClient {  
  2.     public String[][] getTD() {  
  3.         String[][] a = {{"城市""销售员""销售额"},{"江苏""Anna""230"},{"江苏""Alex""190"},{"江苏","Jack","320"},{"江苏","Apple","210"},{"浙江","Faye","150"},{"浙江","Sammi","280"}};  
  4.         return a;  
  5.     }  
  6. }  
以jws方式发布WebService:将写好的TestWS2TDClient.java文件重命名为TestWS2TDClient.jws,放在Tomcat\webapps\axis2即可。
1.2 在java类中访问WebService数据源
java中发送一个soap请求,访问TestWS2TDClient.jws这个WebService,得到返回的数据,代码如下:
  1. try {  
  2.     String endpoint = "http://localhost:8080/axis/TestWS2TDClient.jws";  
  3.     Service service = new Service(); //创建一个服务(service)调用(call)  
  4.     Call call = (Call) service.createCall(); // 通过service创建call对象  
  5.     call.setTargetEndpointAddress(new java.net.URL(endpoint)); // 设置service所在URL  
  6.     call.setOperationName(new QName("http://localhost:8080/axis/TestWS2TDClient.jws","getTD"));  // 调用service中的getTD方法  
  7.     String[][] ret = (String[][])call.invoke(new Object[] {}); // getTD方法没有参数,因此传一个空的对象,得到service中getTD返回的数据  
  8.     return ret;  
  9. catch (Exception e) {  
  10.     e.printStackTrace();  
  11. }  
注:soap即简单对象访问协议,客户端发送一个请求,调用相应的对象, 然后服务器返回结果。这些消息是XML 格式的,并且封装成符合HTTP 协议的消息。
需要引入axis.jar、commons-discovery-0.2.jar、commons-logging-1.0.4.jar、wsdl4j-1.5.1.jar、log4j-1.2.8.jar、jaxrpc.jar六个包,可以在axis\WEB-INF\lib下找到。
1.3 将获得数据转为程序数据集
访问WebService后,该服务会返回数据给客户端,该例中返回一个字符串数组。定义WebServiceTableData.java类,扩展AbstractTableData,将获得的数组数据转为程序数据集。完整代码如下:
  1. package com.fr.data;  
  2.   
  3. import javax.xml.namespace.QName;  
  4. import org.apache.axis.client.Call;  
  5. import org.apache.axis.client.Service;  
  6. import com.fr.data.AbstractTableData;  
  7. import com.fr.data.TableDataException;  
  8.   
  9. public class WebServiceTableData extends AbstractTableData{  
  10.     private String[][] data;  
  11.       
  12.     public WebServiceTableData() {  
  13.         this.data = this.getData();  
  14.     }  
  15.   
  16.     //获取列数  
  17.     public int getColumnCount() throws TableDataException {  
  18.         return data[0].length;  
  19.     }  
  20.   
  21.     //获取列的名称为数组中第一行的值  
  22.     public String getColumnName(int columnIndex) throws TableDataException {  
  23.         return data[0][columnIndex];  
  24.     }  
  25.   
  26.     //获取行数为数据的长度-1  
  27.     public int getRowCount() throws TableDataException {  
  28.         return data.length - 1;  
  29.     }  
  30.   
  31.     //获取值  
  32.     public Object getValueAt(int rowIndex, int columnIndex) {  
  33.         return data[rowIndex + 1][columnIndex];  
  34.     }  
  35.   
  36.     public String[][] getData() {  
  37.         try {  
  38.             String endpoint = "http://localhost:8080/axis/TestWS2TDClient.jws";  
  39.             Service service = new Service();  
  40.             Call call = (Call) service.createCall();  
  41.             call.setTargetEndpointAddress(new java.net.URL(endpoint));  
  42.             call.setOperationName(new QName("http://localhost:8080/axis/TestWS2TDClient.jws",  
  43.                     "getTD"));  
  44.             String[][] ret = (String[][])call.invoke(new Object[] {});  
  45.             return ret;  
  46.         } catch (Exception e) {  
  47.             e.printStackTrace();  
  48.         }  
  49.         return new String[][] {};  
  50.     }  
  51. }  
注:最新的代码链接fine-help
将编译好的class文件拷贝到%FR_HOME%/WebReport/WEB-INF/classes/com/fr/data文件夹下。
1.4 设计器中调用程序数据集
新建报表,定义数据集,选择程序数据集,选择定义好的程序数据集WebServiceTableData.class,自定义数据集的名称为ds1,启动tomcat服务器,点击预览,效果如下:

 

WebService程序数据集之WSDL取数 编辑

1. 问题描述
     使用通用的webservice集合,在集合中使用wsdl取数的方式获取数据,并将数据转换为程序数据集,那么怎样通过wsdl取数并转换为程序数据集呢?
2. 解决思路
首先将wsdl获取到的数据转换为二维数组,然后通过FineReport的程序数据集接口,将数据导入到接口中,wsdl取数的方式有三种,RPC方式调用、document方式调用以及通过axis2 的wsdl2java.bat生成客户端调用,前两种方式不生成客户端代码,比较繁琐,最后一种方式生成客户端代码,但是比较简洁,下面介绍第二种和第三种方式。
使用通用的webservice集合作为数据来源,访问通用webservice集合可任意选择一个web服务,这里使用国内手机号码归属地查询WEB服务,wsdl地址为:http://webservice.webxml.com.cn/WebServices/MobileCodeWS.asmx?wsdl 
在浏览器中输入上述wsdl文件的地址,可得知,该wsdl中定义了两个取数函数,getDatabaseInfo 和getMobileCodeInfo ,前者无参数传入,后者需要传入mobileCode参数。
注:在eclipse中编写wsdl取数代码时,首先需要导入如下的jar包:
FineReport的2个包放在%FR_Home%/WebReport/WEB_INF/lib里面,sjsxp-1.0.1.jar的下载地址为sjsxp-1.0.1.jar
另:axis2的jar包必须保持版本一致,下载地址为:WSDL—axis2
3. document方式调用
以上述wsdl为例,使用getDatabaseInfo函数,不传入参数,document方式调用函数代码如下:
3.1 wsdl数据获取
  1. try {  
  2.             // 指定调用WebService的URL  
  3.             String url = "http://www.webxml.com.cn/WebServices/MobileCodeWS.asmx?wsdl";  
  4.             EndpointReference targetEPR = new EndpointReference(url);  
  5.             // 创建一个OMFactory,下面的namespace、方法与参数均需由它创建  
  6.             OMFactory fac = OMAbstractFactory.getOMFactory();  
  7.             // 命名空间  
  8.             OMNamespace omNs = fac.createOMNamespace("http://WebXml.com.cn","a");  
  9.             // 下面创建的是参数对数  
  10.             /* 
  11.              * OMElement symbol = fac.createOMElement("mobileCode", omNs); 
  12.              * symbol.addChild(fac.createOMText(symbol, "18795842")); 
  13.              */  
  14.             // 下面创建一个method对象 ,方法  
  15.             OMElement method = fac.createOMElement("getDatabaseInfo", omNs);  
  16.             // method.addChild(symbol);  
  17.             Options options = new Options();  
  18.             options.setTo(targetEPR);  
  19.             options.setAction("http://WebXml.com.cn/getDatabaseInfo");  
  20.             ServiceClient sender = new ServiceClient();  
  21.             sender.setOptions(options);  
  22.             OMElement result1 = sender.sendReceive(method);  
  23.         } catch (AxisFault axisFault) {  
  24.             axisFault.printStackTrace();  
  25.         }  
注:如果使用getMobileCodeInfo函数,传入参数, 那么需要创建参数对,在上述代码中被注释的部分。
3.2 OMElement对象转换
由于document方式函数调用取数方式获取到的数据为OMElement对象,所以需要将OMElement转换为二维数组,转换函数代码如下:
  1.  public static String[][] getResults(OMElement element) {  
  2.         if (element == null) {  
  3.             return null;  
  4.         }  
  5.         Iterator iterator = element.getChildElements();  
  6.         Iterator innerItr;  
  7.         List<String> list = new ArrayList<String>();  
  8.         OMElement result = null;  
  9.         while (iterator.hasNext()) {  
  10.             result = (OMElement) iterator.next();  
  11.             innerItr = result.getChildElements();  
  12.             while (innerItr.hasNext()) {   
  13.                 OMElement elem = (OMElement)innerItr.next();    
  14.                list.add(elem.getText());  
  15.             }  
  16.         }  
  17.         String[] result1 = list.toArray(new String[list.size()]);  
  18.         String results[][] = new String[result1.length][3];  
  19.         String b1, b2, b3;  
  20.         for (int i = 0; i < result1.length; i++) {  
  21.             if (result1[i].length() != 0) {  
  22.                 b1 = result1[i].substring(0, result1[i].indexOf(" "));  
  23.                 b2 = result1[i].substring(result1[i].indexOf(" ") + 1).substring(0,result1[i].substring(result1[i].indexOf(" ") + 1).indexOf(" "));  
  24.                 b3 = result1[i].substring(result1[i].indexOf(" ") + 1).substring(result1[i].substring(result1[i].indexOf(" ") + 1).indexOf(" ") + 1);  
  25.                 results[i][0] = b1;  
  26.                 results[i][1] = b2;  
  27.                 results[i][2] = b3;  
  28.                   
  29.             }  
  30.         }  
  31.         return results;  
  32. }  
3.3 获取数据转换为程序数据集
定义WebServiceTableWsdlDataDemo.java类,扩展AbstractTableData,将获得的数组数据转为程序数据集。完整代码如下:
  1. package com.fr.data;  
  2.   
  3. import java.util.ArrayList;  
  4. import java.util.Iterator;  
  5. import java.util.List;  
  6. import org.apache.axiom.om.OMAbstractFactory;  
  7. import org.apache.axiom.om.OMElement;  
  8. import org.apache.axiom.om.OMFactory;  
  9. import org.apache.axiom.om.OMNamespace;  
  10. import org.apache.axis2.addressing.EndpointReference;  
  11. import org.apache.axis2.client.Options;  
  12. import org.apache.axis2.client.ServiceClient;  
  13. import com.fr.general.data.TableDataException;  
  14.   
  15. public class MobileWsdlTableDataDemo extends AbstractTableData{  
  16.     private String[][] data;    
  17.       
  18.     public MobileWsdlTableDataDemo() {    
  19.         this.data = this.getData();    
  20.     }  
  21.       
  22.     public int getColumnCount() throws TableDataException {    
  23.         return data[0].length;    
  24.     }    
  25.     
  26.     //获取列的名称为数组中第一行的值    
  27.     public String getColumnName(int columnIndex) throws TableDataException {    
  28.         return data[0][columnIndex];    
  29.     }    
  30.     
  31.     //获取行数为数据的长度-1    
  32.     public int getRowCount() throws TableDataException {    
  33.         return data.length - 1;    
  34.     }    
  35.     
  36.     //获取值    
  37.     public Object getValueAt(int rowIndex, int columnIndex) {    
  38.         return data[rowIndex + 1][columnIndex];    
  39.     }    
  40.     
  41.     public static String[][] getResults(OMElement element) {  
  42.         if (element == null) {  
  43.             return null;  
  44.         }  
  45.         Iterator iterator = element.getChildElements();  
  46.         Iterator innerItr;  
  47.         List<String> list = new ArrayList<String>();  
  48.         OMElement result = null;  
  49.         while (iterator.hasNext()) {  
  50.             result = (OMElement) iterator.next();  
  51.             innerItr = result.getChildElements();  
  52.             while (innerItr.hasNext()) {   
  53.                 OMElement elem = (OMElement)innerItr.next();    
  54.                list.add(elem.getText());  
  55.             }  
  56.         }  
  57.         String[] result1 = list.toArray(new String[list.size()]);  
  58.         String results[][] = new String[result1.length][3];  
  59.         String b1, b2, b3;  
  60.         for (int i = 0; i < result1.length; i++) {  
  61.             if (result1[i].length() != 0) {  
  62.                 b1 = result1[i].substring(0, result1[i].indexOf(" "));  
  63.                 b2 = result1[i].substring(result1[i].indexOf(" ") + 1).substring(0,result1[i].substring(result1[i].indexOf(" ") + 1).indexOf(" "));  
  64.                 b3 = result1[i].substring(result1[i].indexOf(" ") + 1).substring(result1[i].substring(result1[i].indexOf(" ") + 1).indexOf(" ") + 1);  
  65.                 results[i][0] = b1;  
  66.                 results[i][1] = b2;  
  67.                 results[i][2] = b3;  
  68.             }  
  69.         }  
  70.         return results;  
  71. }  
  72.   
  73.    
  74.     public String[][] getData() {  
  75.         try {  
  76.             String url = "http://www.webxml.com.cn/WebServices/MobileCodeWS.asmx?wsdl";  
  77.               EndpointReference targetEPR = new EndpointReference(url);             
  78.               //创建一个OMFactory,下面的namespace、方法与参数均需由它创建    
  79.               OMFactory fac = OMAbstractFactory.getOMFactory();  
  80.               // 命名空间  
  81.               OMNamespace omNs = fac.createOMNamespace("http://WebXml.com.cn""a");  
  82.               //下面创建的是参数对数  
  83.              /*  
  84.               *OMElement symbol = fac.createOMElement("mobileCode", omNs); 
  85.               symbol.addChild(fac.createOMText(symbol, "18795842")); 
  86.               */  
  87.               //下面创建一个method对象  ,方法  
  88.               OMElement method = fac.createOMElement("getDatabaseInfo", omNs);  
  89.               // method.addChild(symbol);               
  90.               Options options = new Options();              
  91.               options.setTo(targetEPR);  
  92.               options.setAction("http://WebXml.com.cn/getDatabaseInfo");  
  93.               ServiceClient sender = new ServiceClient();  
  94.               sender.setOptions(options);      
  95.               OMElement result1 = sender.sendReceive(method);  
  96.               String[][] result = getResults(result1);  
  97.              return result;  
  98.         } catch (org.apache.axis2.AxisFault e) {  
  99.             e.printStackTrace();  
  100.         } catch (java.rmi.RemoteException e) {  
  101.             e.printStackTrace();  
  102.         }  
  103.         return new String[][] { {} };  
  104.     }  
  105.    
  106.     }  
注:最新的代码链接fine-help
将编译好的class文件拷贝到%FR_HOME%/WebReport/WEB-INF/classes/com/fr/data文件夹下。
3.4 设计器中调用程序数据集
新建报表,定义数据集,选择程序数据集,选择定义好的程序数据集WebServiceWsdlTableDataDemo.class,点击预览,效果如下:
注:在设计器中调用程序数据集,同样要将上述导入到eclipse中的jar包拷贝到%FR_HOME\WebReport\WEB-INF\lib目录下,否则预览是没有数据的。
4. 通过axis2生成客户端调用
Axis2提供了一个wsdl2java.bat命令可以根据WSDL文件自动产生调用WebService的代码。
4.1 wsdl2java.bat生成代码
进入axis2的bin目录执行如下的命令:
  1. wsdl2java -uri http://webservice.webxml.com.cn/WebServices/MobileCodeWS.asmx?wsdl -p mobile -o mobile  
如下图:
uri:wsdl文件地址,可以是本地路径,也可以是网络路径;
-p:指定了生成的Java类的包名;
-o:指定了生成的一系列文件保存的根目录。
wsdl2java.bat插件还有很多参数,这里不一一详述了。
命令语句执行完成之后,在参数-o指定的文件目录里面就能看到生成的WebService代码了,这里指定的目录为当前目录下面的mobile文件夹(如果没有改文件夹,会自动新建),如下图:
4.2 通过生成的WebService代码取数
在eclipse中新建一个java 工程,将上一步骤生成的WebService代码即2个java文件所在的包一起拷到该工程的src目录中,如下图:
这样就可以直接使用工程中的MobileCodeWSStub类,从wsdl取数,并转换为二维数组,代码如下:
  1. try {  
  2.               String url = "http://www.webxml.com.cn/WebServices/MobileCodeWS.asmx?wsdl";  
  3.               MobileCodeWSStub stub = new MobileCodeWSStub(url);  
  4. //            MobileCodeWSStub.GetMobileCodeInfo aa = new MobileCodeWSStub.GetMobileCodeInfo();  
  5.               MobileCodeWSStub.GetDatabaseInfo bb = new MobileCodeWSStub.GetDatabaseInfo();  
  6. //            aa.setMobileCode("18795842832");  
  7. //            String rs=stub.getMobileCodeInfo(aa).getGetMobileCodeInfoResult();  
  8.              String[] p=stub.getDatabaseInfo(bb).getGetDatabaseInfoResult().getString();  
  9.              String result[][] = new String[p.length][3];  
  10.              String b1,b2,b3;  
  11.              for(int i = 0;i<p.length;i++)  
  12.              {               
  13.                  if(p[i].length()!=0)  
  14.                  {  
  15.                b1 = p[i].substring(0, p[i].indexOf(" "));  
  16.                b2 = p[i].substring(p[i].indexOf(" ")+1).substring(0,p[i].substring(p[i].indexOf(" ")+1).indexOf(" "));  
  17.                b3 = p[i].substring(p[i].indexOf(" ")+1).substring(p[i].substring(p[i].indexOf(" ")+1).indexOf(" ")+1);  
  18.                result[i][0] = b1;  
  19.                result[i][1] = b2;  
  20.                result[i][2] = b3;  
  21.             }             
  22.            }  
  23.              return result;  
  24.         } catch (org.apache.axis2.AxisFault e) {  
  25.             e.printStackTrace();  
  26.         } catch (java.rmi.RemoteException e) {  
  27.             e.printStackTrace();  
  28.         }  
  29.         return new String[][] { {} };  
  30.     }  
4.3 获取数据转换为程序数据集
定义WebServiceWsdlTableDataDemo2.java类,扩展AbstractTableData,将获得的数组数据转为程序数据集。完整代码如下:
  1. package com.fr.data;  
  2.   
  3. import java.util.logging.Logger;  
  4. import moblie.MobileCodeWSStub;  
  5. import org.apache.axis2.AxisFault;  
  6. import org.apache.axis2.addressing.EndpointReference;  
  7. import org.apache.axis2.client.Options;  
  8. import org.apache.axis2.rpc.client.RPCServiceClient;  
  9. import com.fr.general.data.TableDataException;  
  10. import com.fr.third.javax.xml.namespace.QName;  
  11.   
  12. public class MobileWsdlTableDataDemo2 extends AbstractTableData{  
  13.     private String[][] data;    
  14.       
  15.     public MobileWsdlTableDataDemo2() {    
  16.         this.data = this.getData();    
  17.     }  
  18.       
  19.     public int getColumnCount() throws TableDataException {    
  20.         return data[0].length;    
  21.     }    
  22.     
  23.     //获取列的名称为数组中第一行的值    
  24.     public String getColumnName(int columnIndex) throws TableDataException {    
  25.         return data[0][columnIndex];    
  26.     }    
  27.     
  28.     //获取行数为数据的长度-1    
  29.     public int getRowCount() throws TableDataException {    
  30.         return data.length - 1;    
  31.     }    
  32.     
  33.     //获取值    
  34.     public Object getValueAt(int rowIndex, int columnIndex) {    
  35.         return data[rowIndex + 1][columnIndex];    
  36.     }    
  37.     
  38.     public String[][] getData() {  
  39.          try {  
  40.               String url = "http://www.webxml.com.cn/WebServices/MobileCodeWS.asmx?wsdl";  
  41.               MobileCodeWSStub stub = new MobileCodeWSStub(url);  
  42. //            MobileCodeWSStub.GetMobileCodeInfo aa = new MobileCodeWSStub.GetMobileCodeInfo();  
  43.               MobileCodeWSStub.GetDatabaseInfo bb = new MobileCodeWSStub.GetDatabaseInfo();  
  44. //            aa.setMobileCode("18795842832");  
  45. //            String rs=stub.getMobileCodeInfo(aa).getGetMobileCodeInfoResult();  
  46.              String[] p=stub.getDatabaseInfo(bb).getGetDatabaseInfoResult().getString();  
  47.              String result[][] = new String[p.length][3];  
  48.              String b1,b2,b3;  
  49.              for(int i = 0;i<p.length;i++)  
  50.              {               
  51.                  if(p[i].length()!=0)  
  52.                  {  
  53.                b1 = p[i].substring(0, p[i].indexOf(" "));  
  54.                b2 = p[i].substring(p[i].indexOf(" ")+1).substring(0,p[i].substring(p[i].indexOf(" ")+1).indexOf(" "));  
  55.                b3 = p[i].substring(p[i].indexOf(" ")+1).substring(p[i].substring(p[i].indexOf(" ")+1).indexOf(" ")+1);  
  56.                result[i][0] = b1;  
  57.                result[i][1] = b2;  
  58.                result[i][2] = b3;  
  59.             }             
  60.            }  
  61.              return result;  
  62.         } catch (org.apache.axis2.AxisFault e) {  
  63.             e.printStackTrace();  
  64.         } catch (java.rmi.RemoteException e) {  
  65.             e.printStackTrace();  
  66.         }  
  67.         return new String[][] { {} };  
  68.     }  
  69.    
  70.     }  
注:最新的代码链接fine-help
将编译好的class文件拷贝到%FR_HOME%/WebReport/WEB-INF/classes/com/fr/data文件夹下。
4.4 设计器中调用程序数据集
新建报表,定义数据集,选择程序数据集,选择定义好的程序数据集WebServiceWsdlTableDataDemo2.class,点击预览,效果如下:

注:在设计器中调用程序数据集,同样要将上述导入到eclipse中的jar包拷贝到%FR_HOME\WebReport\WEB-INF\lib目录下,否则预览是没有数据的。