现在的位置: 首页 > 综合 > 正文

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

2013年04月16日 ⁄ 综合 ⁄ 共 3142字 ⁄ 字号 评论关闭

由于工作上有一个通过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,参见另一篇文章

 

 

 

抱歉!评论已关闭.