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,参见另一篇文章

 

 

 

你可能感兴趣的:(server)