WCF C#DataTable 与 安卓Cursor互转 JAVA亦可参考

原理:WCF属于webservice,我们使用soapUI获取WCF所有请求类型,及请求参数的XML格式,封装成安卓端请求。

依赖
app.build.gradle
android {
...
	packagingOptions {
        exclude 'META-INF/DEPENDENCIES'
        exclude 'META-INF/NOTICE'
        exclude 'META-INF/LICENSE'
        exclude 'META-INF/MANIFEST.MF'
        exclude 'mozilla/public_suffix-list.txt'
        exclude 'META-INF/maven/org.apache.httpcomponents/httpcore/pom.properties'
        exclude 'META-INF/maven/org.apache.httpcomponents/httpcore/pom.xml'
    }
    ...
}    

implementation group: 'org.apache.httpcomponents.client5' , name: 'httpclient5' , version: '5.0-beta4'
发送请求
new Thread(()->{
           String retStr;//返回结果
           String soapXML;//自己构建XML请求参数
           CloseableHttpClient closeableHttpClient = null;
           try {
               closeableHttpClient = HttpClientBuilder.create().build();
               try {
                   HttpPost httpPost = new HttpPost("填写服务器域名及端口号");
                   RequestConfig requestConfig = RequestConfig.custom()
                           .setConnectTimeout(Timeout.ofSeconds(ConnectTimeout))
                           .setResponseTimeout(Timeout.ofSeconds(ResponseTimeout)).build();// 设置请求和传输超时时间
                   httpPost.setConfig(requestConfig);
                   httpPost.setHeader("Content-Type", "text/xml;charset=UTF-8");
                   httpPost.setHeader("SOAPAction", "这里填你的WCF服务及类型");
                   httpPost.setEntity(new StringEntity(new String(soapXML.getBytes(), Charset.forName("UTF-8"))));

                   CloseableHttpResponse response = closeableHttpClient.execute(httpPost);

                   String strData = EntityUtils.toString(response.getEntity(), Charset.forName("UTF-8"));
                   retStr = "Response:\n"+response.toString() + "\n" + response.getEntity().toString() + "\n" + strData;
               } catch (Exception e) {
                   retStr = null;
                   e.printStackTrace();
               }
           }
           finally {
               try {closeableHttpClient.close();}catch(Exception e){}
           }
       }).start();
XML互转工具
//region DataTable与Cursor转换工具
    /**
     * 此函数将游标内的数据转换成xml
     * @param cursor
     * @param DataAppend
     * DataAppend[0] TableAppend
     * DataAppend[1] RowAppend
     * @return
     */
    public static String CursorToXML(final Cursor cursor ,Handler handler,String...DataAppend){
        String Tables = "";
        String RowsFormat ="<Table diffgr:id=\"Table%d\" msdata:rowOrder=\"%d\">";
        cursor.moveToFirst();
        //region 添加表结构信息
        for(int i =0,ni = cursor.getColumnCount();i<ni;++i){
            String TableColumnType = null;
            switch (cursor.getType(i)){
                case Cursor.FIELD_TYPE_INTEGER:
                    TableColumnType = "int";
                    break;
                case Cursor.FIELD_TYPE_STRING:
                    TableColumnType = "string";
                    break;
                case Cursor.FIELD_TYPE_BLOB:
                    TableColumnType = "blob";
                    break;
                case Cursor.FIELD_TYPE_FLOAT:
                    TableColumnType = "decimal";
            }
            if(TableColumnType!=null){
                RowsFormat = RowsFormat + String.format("<%s>%%s</%s>",cursor.getColumnName(i),cursor.getColumnName(i));
                Tables = String.format("%s <xs:element name=\"%s\" type=\"xs:%s\" minOccurs=\"0\"/>",Tables,cursor.getColumnName(i),TableColumnType);
            }
        }
        cursor.moveToPrevious();
        //endregion

        //region 添加表行记录信息
        if(DataAppend!=null&&DataAppend.length>0) Tables=Tables+DataAppend[0];
        RowsFormat=RowsFormat+"</Table>";
        String Rows = "";
        for (int i=0;cursor.moveToNext();++i){
            try {if(i%100==0)Message.obtain(handler,WCFState_SoapProgress,100).sendToTarget();} catch (Exception e) {}
            Object [] oParams = new Object[cursor.getColumnCount()+2];
            oParams[0] = i+1;
            oParams[1] = i;
            for(int j=0,nj=cursor.getColumnCount();j<nj;++j) oParams[j+2] = cursor.getString(j);
            Rows = Rows + String.format(RowsFormat,oParams);
        }
        //endregion
        String DataTable = String.format("%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s",
                "<xs:schema id=\"NewDataSet\" xmlns:xs=\"http://www.w3.org/2001/XMLSchema\" xmlns=\"\" xmlns:msdata=\"urn:schemas-microsoft-com:xml-msdata\">" ,
                    "<xs:element name=\"NewDataSet\" msdata:IsDataSet=\"true\" msdata:MainDataTable=\"Table\" msdata:UseCurrentLocale=\"true\">" ,
                        "<xs:complexType>" ,
                            "<xs:choice minOccurs=\"0\" maxOccurs=\"unbounded\">" ,
                                "<xs:element name=\"Table\">" ,
                                    "<xs:complexType>" ,
                                        "<xs:sequence>" ,
                                            Tables,
                                        "</xs:sequence>" ,
                                    "</xs:complexType>" ,
                                "</xs:element>" ,
                            "</xs:choice>" ,
                        "</xs:complexType>" ,
                    "</xs:element>" ,
                "</xs:schema>" ,

                "<diffgr:diffgram xmlns:diffgr=\"urn:schemas-microsoft-com:xml-diffgram-v1\" xmlns:msdata=\"urn:schemas-microsoft-com:xml-msdata\">" ,
                    "<NewDataSet xmlns=\"\">" ,
                        Rows,
                    "</NewDataSet>" ,
                "</diffgr:diffgram>"
        );
        return DataTable;
    }

    /**
     * 此函数将响应的DataTable数据段转换为安卓Cursor
     * 注意此函数返回Cursor部分功能未实现
     * @param DataTable
     * @return
     */
    public static Cursor XmlToCursor(final String DataTable){
        List<List<String>> tDatas = new LinkedList<>();//临时数据
        Map<String, Integer> tNames = new HashMap<>();//临时列名与列号对应
        Map<Integer, String> tIndexs= new HashMap<>();//临时列号与列名对应
        List<Integer> tTypes = new LinkedList<>();//列号对应数据类型
        //region 添加表信息
        try {
            String TableInfo = DataTable.substring(DataTable.indexOf("<xs:sequence>")+"<xs:sequence>".length(),DataTable.indexOf("</xs:sequence>"));
            for (int i=0,idxName,idxType,idxEnd,lenName="<xs:element name=\"".length(),lenType="\" type=\"".length();(idxName=TableInfo.indexOf("<xs:element name=\""))>-1&&(idxType=TableInfo.indexOf("\" type=\""))>-1;++i){
                String Name = TableInfo.substring(idxName+lenName,idxType);
                idxEnd = TableInfo.indexOf("\"",idxType+lenType);
                String Type = TableInfo.substring(idxType+lenType,idxEnd);
                tIndexs.put(i,Name);
                tNames.put(Name,i);
                switch (Type){
                    case "xs:string":
                        tTypes.add(Cursor.FIELD_TYPE_STRING);
                        break;
                    case "xs:int":
                        tTypes.add(Cursor.FIELD_TYPE_INTEGER);
                        break;
                    case "xs:blob":
                        tTypes.add(Cursor.FIELD_TYPE_BLOB);
                        break;
                    case "xs:decimal":
                        tTypes.add(Cursor.FIELD_TYPE_FLOAT);
                        break;
                }
                TableInfo=TableInfo.substring(idxEnd);
            }
        } catch (Exception e) {}
        //endregion

        //region 处理数据集
        try{
            String RecordInfo = DataTable.substring(DataTable.indexOf("<NewDataSet xmlns=\"\">")+"<NewDataSet xmlns=\"\">".length(),DataTable.indexOf("</NewDataSet>"));
            for(int i=0,idxBegin,idxEnd;;++i){
                String rowBegin = String.format("<Table diffgr:id=\"Table%d\" msdata:rowOrder=\"%d\">",i+1,i);
                idxBegin = RecordInfo.indexOf(rowBegin)+rowBegin.length();
                idxEnd = RecordInfo.indexOf("</Table>",idxBegin);
                //region 添加行记录
                String RowsInfo=RecordInfo.substring(idxBegin,idxEnd);
                RecordInfo=RecordInfo.substring(idxEnd);
                List<String> RowData = new LinkedList<>();
                try {
                    while(true){
                        idxEnd = RowsInfo.indexOf('<',idxBegin = RowsInfo.indexOf('>')+1);
                        RowData.add(RowsInfo.substring(idxBegin,idxEnd));
                        RowsInfo=RowsInfo.substring((RowsInfo.substring(0,idxEnd).contains("/>")?idxEnd:RowsInfo.indexOf('>',idxEnd))+1);
                    }
                } catch (Exception e) {e.printStackTrace();}
                tDatas.add(RowData);
                //endregion
            }
        }catch (Exception e){e.printStackTrace();}
        //endregion
        final List<List<String>> cDatas = tDatas;
        final List<Integer> cTypes = tTypes;
        final Map<String, Integer> cNames = tNames;
        final Map<Integer, String> cIndexs = tIndexs;
        return new Cursor() {
            private int pIndex = -1;
            private List<Integer> cColumnTypes = cTypes;
            private List<List<String>> cRecords = cDatas;
            private Map<String, Integer> cColumnNames = cNames;
            private Map<Integer, String> cColumnIndexs = cIndexs;
            @Override
            public int getCount() { return cRecords==null?0:cRecords.size(); }
            @Override
            public int getPosition() { return pIndex; }
            @Override
            public boolean move(int i) { return (i<-1&&i>=cRecords.size())?false:((pIndex=i)==i); }
            @Override
            public boolean moveToPosition(int i) { return move(i); }
            @Override
            public boolean moveToFirst() { return getCount()>0&&(pIndex=0)==0; }
            @Override
            public boolean moveToLast() { return getCount()>0&&(pIndex=getCount())>0; }
            @Override
            public boolean moveToNext() { return getCount()>(pIndex+1)&&((pIndex=pIndex+1)>-1); }//溢出处理
            @Override
            public boolean moveToPrevious() { return getCount()>0&&pIndex-1>0&&((pIndex=pIndex-1)>-1); }
            @Override
            public boolean isFirst() { return pIndex==0; }
            @Override
            public boolean isLast() { return pIndex==getCount(); }
            @Override
            public boolean isBeforeFirst() { return pIndex==-1; }
            @Override
            public boolean isAfterLast() { return pIndex==getCount(); }
            @Override
            public int getColumnIndex(String s) { return cColumnNames.get(s); }
            @Override
            public int getColumnIndexOrThrow(String s) throws IllegalArgumentException { return cColumnNames.get(s); }
            @Override
            public String getColumnName(int i) { return cColumnIndexs.get(i); }
            @Override
            public String[] getColumnNames() {
                String str[] = new String[cColumnIndexs.size()];
                for(int i=0;i<str.length;++i)str[i]=cColumnIndexs.get(i);
                return str;
            }
            @Override
            public int getColumnCount() { return cColumnNames.size(); }
            @Override
            public byte[] getBlob(int i) { return cRecords.get(pIndex).get(i).getBytes(); }
            @Override
            public String getString(int i) { return cRecords.get(pIndex).get(i); }
            @Override
            public void copyStringToBuffer(int i, CharArrayBuffer charArrayBuffer) { }
            @Override
            public short getShort(int i) { return Short.parseShort(getString(i)); }
            @Override
            public int getInt(int i) { return Integer.parseInt(getString(i)); }
            @Override
            public long getLong(int i) { return Long.parseLong(getString(i)); }
            @Override
            public float getFloat(int i) { return Float.parseFloat(getString(i)); }
            @Override
            public double getDouble(int i) { return Double.parseDouble(getString(i)); }
            @Override
            public int getType(int i) { return cColumnTypes.get(i);}
            @Override
            public boolean isNull(int i) { return getString(i)==null; }
            @Override
            public void deactivate() {}
            @Override
            public boolean requery() { return false; }
            @Override
            public void close() {}
            @Override
            public boolean isClosed() { return false; }
            @Override
            public void registerContentObserver(ContentObserver contentObserver) {}
            @Override
            public void unregisterContentObserver(ContentObserver contentObserver) {}
            @Override
            public void registerDataSetObserver(DataSetObserver dataSetObserver) {}
            @Override
            public void unregisterDataSetObserver(DataSetObserver dataSetObserver) {}
            @Override
            public void setNotificationUri(ContentResolver contentResolver, Uri uri) {}
            @Override
            public Uri getNotificationUri() { return null;}
            @Override
            public boolean getWantsAllOnMoveCalls() { return false; }
            @Override
            public void setExtras(Bundle bundle) {}
            @Override
            public Bundle getExtras() { return null; }
            @Override
            public Bundle respond(Bundle bundle) { return null; }
        };
    }
    //endregion
发布了107 篇原创文章 · 获赞 21 · 访问量 3万+

猜你喜欢

转载自blog.csdn.net/best335/article/details/103545839
WCF
今日推荐