• AE访问arcserver的rest服务(vc实现,json格式)


    由于工作上有一个通过AE访问arcserver服务的需求,就做了一些这方面的工作。访问地图的方式,已经有很多人写过了,我就不在这里赘述了。我这里主要内容是查询方面的功能,通过访问rest接口,返回json串,然后再解析json。

    这里涉及到两个主要的知识点

    1,http协议方面内容

    2,json解析

    http可以通过CInternetSession,CHttpConnection,CHttpFile等类来操作,还是比较方便的。

    json可以通过三方库来完成,jsoncpp和boost是比较常见的两个,我这里采用了jsoncpp。boost的功能比较强悍,还可以解析xml,ini等,不过也有一些已知的bug。jsoncpp我这里使用没发现bug,不过有人反映这个效率不是很高。

    jsoncpp(jsoncpp-src-0.5.0)大家可以通过官网去下载,我是用vs2008编译的,开始编译遇到很多莫名奇妙的问题,其实只要在编译前制定编码方式为unicode,release模式关闭优化,编译就没问题。

    这里贴几段主要的代码,最后提供测试代码给大家下载

    通过post方式查询,这个查询里面要注意转码,从unicode转换为utf-8。

    //strServer 服务器地址
    //strObjectName 比如/ArcGIS/rest/services/yongdiguihuazongtuceng/MapServer/1/query? 包含了图层名,类型,索引
    //nPort 指定了端口,默认为80
    void MyHttp::MyHttpPost( CString strServer,CString strObjectName,CString strQuery,int nPort,string &json )
    {
        json = "";
        CInternetSession session(NULL,1,INTERNET_OPEN_TYPE_DIRECT,NULL,NULL,0);
        CHttpConnection* pConnection=NULL;
        CHttpFile* pFile=NULL;
        INTERNET_PORT port=nPort;
    
        session.SetOption(INTERNET_OPTION_CONNECT_TIMEOUT, 10*1000); 
        pConnection = session.GetHttpConnection(strServer,port);
    
        pFile = pConnection->OpenRequest(CHttpConnection::HTTP_VERB_POST,strObjectName);
        CString strHeaders =_T("Content-Type: application/x-www-form-urlencoded\r\n";);
    
        char cQuery[1024]; 
        memset(cQuery,0,sizeof(cQuery)); 
        CodeConvert::UnicodeToUTF8(strQuery,cQuery); 
        string data = "";
        data = cQuery;
    
        try
        {
            if ( pFile->SendRequest(strHeaders,  (LPVOID *)data.c_str(), data.length()) )
            {
                DWORD  StatusCode; 
                pFile->QueryInfoStatusCode(StatusCode); 
    
                if ( HTTP_STATUS_OK == StatusCode )
                {
                    CString strHtml = _T("");
                    CString myData;
                    long i =0;
                    while ( pFile->ReadString ( myData ) )
                    {
                        i++;
                        strHtml += myData;                
                    }
                    CodeConvert::Utf8ToGBK(strHtml);
                    
    
                    //USES_CONVERSION;
                    //调用函数,T2A和W2A均支持ATL和MFC中的字符转换 
                    //这种方法,在strhtml足够大的时候,会引发异常,查询了一下,是栈空间不足,
                    //不过按照提示的方法,没有修复错误,所以使用了另一种方式来实现
                    //char * pHtml = W2A(strHtml);
                    //json = pHtml;
    
                    // Convert a TCHAR string to a LPCSTR   
                    CT2CA pszConvertedAnsiString (strHtml);   
                    // construct a std::string using the LPCSTR input   
                    std::string strStd (pszConvertedAnsiString);  
                    json = strStd;
                }
            }
        }
        catch(...)
        {
    
        }
        session.Close();
        if (NULL != pFile)
        {
            delete pFile;
            pFile = NULL;
        }
        if (NULL != pConnection)
        {
            delete pConnection;
            pConnection = NULL;
        }
        
    

    使用jsoncpp,先包含所需的内容

    #include "json/json.h"
    
    #ifdef _DEBUG
    #pragma comment(lib, "json/json_vc90_libmtd.lib")
    #else
    #pragma comment(lib, "json/json_vc90_libmt.lib")
    #endif
    
    using namespace Json;

    解析json,这里其实了解了json的格式就不难,我这里只是读,涉及到的json::value,注意其各种格式解析就好了

    BOOL MyJson::GetValue( string json,CString strKey,CString &strArr )
    {
        if (json.empty())
        {
            return FALSE;
        }
        strArr = _T("");
        vector<CString> arr;
        USES_CONVERSION; 
        char* s_char=W2A(strKey); 
    
        Reader reader;
        Value value;
        CString str;
        if (reader.parse(json, value))
        {
            Value result = value["features"];
            ValueType vType = result.type();
            if (nullValue == vType)
            {
                return FALSE;
            }
            Value::UInt nSize = result.size();
            for (Value::UInt i=0; i<nSize; i++)
            {
                Value name =  result[i]["attributes"][s_char]; 
                vType = name.type();
                if (nullValue == vType)
                {
                    return FALSE;
                }
                CString s = A2T(name.asCString());
    
                BOOL bAdd = FALSE;
                vector<CString>::iterator iter = arr.begin();
                while(iter != arr.end())
                {
                    if (s.CompareNoCase(*iter) == 0)
                    {
                        bAdd = TRUE;
                        break;
                    }
                    iter ++;
                }
                if (TRUE != bAdd)
                {
                    arr.push_back(s);
                }            
            }
        }
    
        if (arr.size() < 1)
        {
            return FALSE;
        }
        strArr = arr[0];
        for(vector<CString>::size_type i=1; i< arr.size(); i++)
        {
            strArr +=_T(",");
            strArr += arr[i];
        }
    
        return TRUE;
    }

    示例里面包含了put和get方法的实现,json数组的解析

    示例代码下载

    boost库的方式操作json,参见另一篇文章

  • 相关阅读:
    表单验证
    obs 之 OBSObj
    rtmp流媒体协议分析(h264、aac)
    lintcode 508.Wiggle Sort
    SVN备份批处理文件
    防火墙没关导致 ORA-12541: TNS: 无监听程序
    [转]window10系统安装oracle11g时遇到INS-13001环境不满足最低要求
    关键驱动因素、约束和浮动因素
    C#之虚函数 非常清晰全面的讲解
    今天有个朋友问我抽象方法和接口的区别,为了解释清楚这个事情,我在网上看到一篇文章讲的非常好给大家分享一下,也感谢原作者的付出
  • 原文地址:https://www.cnblogs.com/junyuz/p/3092760.html
Copyright © 2020-2023  润新知