HTTP服务端JSON服务端

HTTP服务端JSON服务端

最后更新日期:  2014-5-18

Author: Kagula

阅读前提: CMake工具的基本使用

内容简介:

   CPPCMS是个开源Web开发框架,通过它可以很容易实现HTTP服务和JSON服务,这里介绍CPPCMS开发环境的搭建。写一个CPPCMS测试程序,它建立HTTP服务,向浏览器返回Hello,World页面。CPPCMS依赖的一些第三方库,其它地方已经介绍怎么Build,所以这里不重复了。

环境:Windows8.1 64bit、Visual Studio 2013 Professional SP1

zlib-1.2.8、openssl-1.0.1g、pcre-8.35、icu4c-53_1、  cppcms-1.0.4、Python-3.4.0.、CMake2.8.12.2、

boost 1.55

 

搭建CPPCMS开发环境

CPPCMS依赖zlib、openssl、pcre、icu4c、python和Win SDK等第三方库或工具

 

         在python官网下载、安装python-3.4.0.amd64.msi,不要忘记在向导中勾选,把python.exe的位置加入到系统的环境变量中。

 

我电脑中编译好的库,它们的位置

zlib

头文件位置:D:/SDK/zlib-1.2.8;D:\SDK\zlib-1.2.8\build;

库文件位置:D:/SDK/zlib-1.2.8/build/Release

 

openssl

头文件位置:D:\SDK\openssl-1.0.1g\include

库文件位置:D:\SDK\openssl-1.0.1g\out32dll

 

icu4c

         下载http://download.icu-project.org/files/icu4c/53.1/icu4c-53_1-src.zip文件

打开D:\SDK\icu4c-53_1-src\icu\source\allinone\allinone.sln文件,Build出Release版本即可。

头文件位置:D:\SDK\icu4c-53_1-src\icu\include

库文件位置:;D:\SDK\icu4c-53_1-src\icu\lib

 

pcre

         下载ftp://ftp.csx.cam.ac.uk/pub/software/programming/pcre/pcre-8.35.zip

         使用CMake工具在D:\SDK\pcre-8.35\build\下生成PCRE.sln文件,使用VisualStudio 2013打开并编译即可。

头文件位置:D:/SDK/pcre-8.35;D:\SDK\pcre-8.35\build;

库文件位置:D:\SDK\pcre-8.35\build\Release

 

准备好后就可以构建cppcms库了

 

从cppcms官网下载cppcms-1.0.4.tar.bz2文件并解压缩到“D:\SDK\cppcms-1.0.4”,打开cmake gui工具configure后,出现了很多变量

添加变量

CMAKE_INCLUDE_PATH

类型为filepath

值为

D:/SDK/pcre-8.35;D:\SDK\pcre-8.35\build;D:/SDK/zlib-1.2.8;D:\SDK\zlib-1.2.8\build;D:\SDK\icu4c-53_1-src\icu\include;D:\SDK\openssl-1.0.1g\include

添加变量

CMAKE_LIBRARY_PATH

类型为filepath

值为D:\SDK\pcre-8.35\build\Release;D:/SDK/zlib-1.2.8/build/Release;D:\SDK\icu4c-53_1-src\icu\lib;D:\SDK\openssl-1.0.1g\out32dll;C:\ProgramFiles (x86)\Microsoft SDKs\Windows\v7.1A\Lib

         重新configure后generate。打开新生成的sln文件。BuildSolution有四个选项Debug、MinSizeRel(最小发行版)、Release、RelWithDebInfo(带Debug信息的发行版),我们这里选Release模式build。

 

编译过程中碰到

[1]zconf.h文件找不到的问题,这个文件在我的D:\SDK\zlib-1.2.8\build路径下,给它地址,这个问题解决。

[2]json.cpp 文件 return is_ 代码行通不过, 改为returnbool(is_)即可,因为Visual Studio 2013(C++11标准)要求istream显式(explicitly)转换bool类型。

[3]test_formatting.cpp和test_boundary.cpp源码文件因为出现特殊字符(其实是文件语言编码的问题)导致无法编译,跳过,因为这两个测试项目不能编译,不影响我们以后使用cppcms库。

[4]修改D:\SDK\cppcms-1.0.4\booster\booster\nowide\fstream.h文件第44行,

if(my_base_type::open(convert(s).c_str(),mode)){

修改为

if (std::basic_filebuf<CharType,Traits>::open(s, mode)) {

否则调用CPPCMS的Debug版会挂掉。

[5]由于CPPCMS的Release版本application类的main方法std::string实参释放时会出错,所以我把它改成const char *类型,下面三步是具体步骤

[5-1]“D:\SDK\cppcms-1.0.4\cppcms\application.h”文件第298行

virtual void main(std::string url);

修改为

virtual void main(const char* url);

[5-2]“D:\SDK\cppcms-1.0.4\src\application.cpp”文件第200行

void application::main(std::string  url)

修改为

void application::main(const char* url)

[5-3]“D:\SDK\cppcms-1.0.4\src\url_dispatcher.cpp”文件第49行

[6]修改json_rpc_server相关文件,使json服务可用

[6-1]

“D:\SDK\cppcms-1.0.4\cppcms\rpc_json.h”152行

virtual void main(std::string);

改为

virtual void main(const char*);

 [6-2]“D:\SDK\cppcms-1.0.4\src\rpc_json.cpp”148行

void json_rpc_server::main(std::string/*unused*/)

改为

void json_rpc_server::main(const char*/*unused*/)

 

app_->main(match_[select_]);

修改为

std::string tmp = match_[select_];

app_->main(tmp.c_str());

现在rebuild整个solution, 等待几分钟后,Visual studio 2013提示77个成功,2个失败(刚才说的文件语言编码问题),3个跳过。这样就可以了。Build后的cppcms.dll、cppcms.lib文件在...\cppcms-1.0.4\build\Release目录下可以找到。

 

         下面我们用CPPCMS写一个HelloWorld程序

Hello World

    构建我们的第一个例子时使用了boost库用来把GBK字符串转utf字符串,我计算机的boost库安装路径是“D:\SDK\boost_1_55_0”。

 

         在Visual Studio中新建Win32 控制台项目,AdditonalOptions选项Empty Project。

设置头文件搜索路径

D:\SDK\cppcms-1.0.4

D:\SDK\cppcms-1.0.4\build

D:\SDK\cppcms-1.0.4\booster

D:\SDK\cppcms-1.0.4\build\booster

D:\SDK\boost_1_55_0

 

设置库文件搜索路径

D:\SDK\cppcms-1.0.4\build\booster\Release

D:\SDK\cppcms-1.0.4\build\Release

D:\SDK\boost_1_55_0\stage\lib

 

添加链接库cppcms.lib

 

复制下面7个动态链接库到你项目文件夹中,否则会提示找不到这些DLL文件

D:\SDK\pcre-8.35\build\Release\pcre.dll

D:\SDK\zlib-1.2.8\build\Release\zlib.dll

D:\SDK\cppcms-1.0.4\build\Release\cppcms.dll

D:\SDK\cppcms-1.0.4\build\booster\Release\booster.dll

D:\SDK\icu4c-53_1-src\icu\bin\icuuc53.dll

D:\SDK\icu4c-53_1-src\icu\bin\icudt53.dll

D:\SDK\icu4c-53_1-src\icu\bin\icuin53.dll

添加Source.cpp文件,源代码清单如下

 

[cpp] view plain copy

 

  1. #include <cppcms/application.h>  
  2. #include <cppcms/applications_pool.h>  
  3. #include <cppcms/service.h>  
  4. #include <cppcms/http_response.h>  
  5.   
  6. #include <boost/locale.hpp>  
  7.   
  8. class hello : public cppcms::application {  
  9. public:  
  10.     hello(cppcms::service &srv) :  
  11.         cppcms::application(srv)  
  12.     {  
  13.     }  
  14.     void main(const char* url);  
  15. };  
  16.   
  17. void hello::main(const char* url)  
  18. {  
  19.     //GBK转utf  
  20.     std::string  utfStr =   
  21.         boost::locale::conv::to_utf<char>("<h1>中文测试</h1>\n", "GBK");  
  22.   
  23.     //输出  
  24.     response().out() <<  
  25.         "<html>\n"  
  26.         "<body>\n"  
  27.         <<utfStr<<  
  28.         "</body>\n"  
  29.         "</html>\n";  
  30. }  
  31.   
  32.   
  33. int main(int argc, char ** argv)  
  34. {  
  35.     try  
  36.     {  
  37.         /* 
  38.         命令行参数为 -c configure.js 
  39.         让CPPCMS读取configure.js里我们的配置信息 
  40.         */  
  41.         cppcms::service srv(argc, argv);  
  42.   
  43.         //挂载用户的Web服务,application的继承类hello  
  44.         srv.applications_pool().mount(cppcms::applications_factory<hello>());  
  45.   
  46.         //这里阻塞,等待用户请求  
  47.         srv.run();  
  48.     }  
  49.     catch (std::exception const &e)  
  50.     {  
  51.         std::cerr << e.what() << std::endl;  
  52.     }  
  53. }  

 

 

添加configure.js文件,源代码清单如下

 

[javascript] view plain copy

 

  1. {    
  2.     "service" : {    
  3.         "api" : "http",    
  4.         "port" : 8080    
  5.     },    
  6.     "http" : {    
  7.         "script_names" : [ "/hello" ]    
  8.     }    
  9. }    

 

 

按[F5]以Debug方式运行即可。

现在你可以使用http://localhost:8080/这个地址访问你的HTTP服务器了。

JSon服务器例子

         我测试了下面这个链接中贴出的代码,可以用,但是如果你的测试程序是在Debug模式,你只能调用debug模式编译出来的CPPCMS动态库,如果你是在Release模式,就只能调用Release模式编译出来的CPPCMS动态库,否则会抛出“bad allocation”的错误。

 

 服务端代码

 

[cpp] view plain copy

 

  1. #include <cppcms/application.h>  
  2. #include <cppcms/applications_pool.h>  
  3. #include <cppcms/service.h>  
  4. #include <cppcms/http_response.h>  
  5. #include <cppcms/rpc_json.h>  
  6. #include <cppcms/json.h>  
  7. #include <cppcms/mount_point.h>  
  8. #include <map>  
  9. #include <string>  
  10.   
  11. #include <exception>  
  12. #include <iostream>  
  13.   
  14. /* 
  15. 标题:测试CPPCMS提供的JSON_RPC服务功能 
  16. 来源: 
  17. 使用cppcms开发JSON_RPC服务 
  18. http://www.zeuux.com/group/candcplus/bbs/content/55785/ 
  19.  
  20. */  
  21. using namespace std;  
  22. using cppcms::rpc::json_rpc_server;  
  23. using cppcms::rpc::json_method;  
  24.   
  25. class calc_service : public json_rpc_server {  
  26. public:  
  27.     calc_service(cppcms::service &srv) : json_rpc_server(srv) {  
  28.         bind("sum",  
  29.             json_method(&calc_service::sum, this), method_role);  
  30.         bind("div",  
  31.             json_method(&calc_service::div, this), method_role);  
  32.     }  
  33.     void sum(int x, int y) {  
  34.         cppcms::json::value v;  
  35.         v["x"] = x;  
  36.         v["y"] = y;  
  37.         v["result"] = x + y;  
  38.         return_result(v);  
  39.     }  
  40.     void div(int x, int y) {  
  41.         if (y == 0) {  
  42.             return_error("Division by zero.");  
  43.         }  
  44.         else {  
  45.             return_result(x / y);  
  46.         }  
  47.     }  
  48. };  
  49.   
  50. class hello_service : public json_rpc_server {  
  51. public:  
  52.     hello_service(cppcms::service &srv) : json_rpc_server(srv) {  
  53.         bind("hello",  
  54.             json_method(&hello_service::hello, this), method_role);  
  55.         bind("hello_all",  
  56.             json_method(&hello_service::hello_all, this), method_role);  
  57.         bind("hello_x",  
  58.             json_method(&hello_service::hello_x, this), method_role);  
  59.     }  
  60.     void hello(string name) {  
  61.         string say = "Hello, " + name + ".";  
  62.         return_result(say);  
  63.     }  
  64.     void hello_all(vector<string> names) {  
  65.         string say = "Hello, ";  
  66.         for (unsigned i = 0; i<names.size(); i++) {  
  67.             say += names[i] + " ";  
  68.         }  
  69.         return_result(say);  
  70.     }  
  71.     void hello_x(cppcms::json::value val) {  
  72.         return_result(val);  
  73.     }  
  74. };  
  75.   
  76. int main(int argc, char ** argv)  
  77. {  
  78.     try {  
  79.         cppcms::service srv(argc, argv);  
  80.   
  81.         srv.applications_pool().mount(  
  82.             cppcms::applications_factory<calc_service>(),  
  83.             cppcms::mount_point("/calc")  
  84.             );  
  85.   
  86.         srv.applications_pool().mount(  
  87.             cppcms::applications_factory<hello_service>(),  
  88.             cppcms::mount_point("/hello")  
  89.             );  
  90.         srv.run();  
  91.     }  
  92.     catch (exception const &e) {  
  93.         cerr << e.what() << endl;  
  94.     }  
  95.     return 0;  
  96. }  

 

测试服务端代码的html源码

 

[cpp] view plain copy

 

  1. <html>  
  2. <body>  
  3.     <script type="text/javascript">  
  4.         function call() {  
  5.   
  6.             var xhr = new XMLHttpRequest();  
  7.             xhr.open("post", 'http://localhost:8080/calc');  
  8.             // Required by JSON-RPC over HTTP  
  9.             xhr.setRequestHeader("Content-Type", "application/json");  
  10.   
  11.             // It is better to use real formatter like JSON.js  
  12.             x = parseInt(document.getElementById('x').value);  
  13.             y = parseInt(document.getElementById('y').value);  
  14.             var request = '{"method":"div","params":[' + x + ',' + y + '],"id":1}';  
  15.   
  16.             xhr.onreadystatechange = function () {  
  17.                 if (xhr.readyState === 4) {  
  18.                     res = 'Unknown Error';  
  19.                     if (xhr.status === 200) {  
  20.                         // Don't call eval in real code use some parser  
  21.                         var result = eval('(' + xhr.responseText + ')');  
  22.                         if (result.error == null) {  
  23.                             res = result.result;  
  24.                         }  
  25.                         else {  
  26.                             res = result.error;  
  27.                         }  
  28.                     }  
  29.                     document.getElementById('result').innerHTML = res;  
  30.                 }  
  31.             }  
  32.             xhr.send(request);  
  33.             return false;  
  34.         }  
  35.     </script>  
  36.     <form onsubmit="return call();">  
  37.         <p>  
  38.             <input type="text" id="x" />  
  39.             <input type="submit" value="/" />  
  40.             <input type="text" id="y" /> =  
  41.             <span id="result"></span>  
  42.         </p>  
  43.     </form>  
  44. </body>  
  45. </html>  

configure.js代码

 

 

[javascript] view plain copy

 

  1. {  
  2.     "service" : {  
  3.         "api" : "http",  
  4.         "port" : 8080,  
  5.         },  
  6.     "http" : {  
  7.         "script_names" : [ "/calc","/hello" ]  
  8.     }  
  9. }  

 

 

 

补充阅读资料

CPPCMS在Linux下的编译和安装

http://blog.csdn.NET/csfreebird/article/details/6730623

 

官网的Hello World例子

http://cppcms.com/wikipp/en/page/cppcms_1x_tut_hello

 

深入学习 CppCMS

http://remonstrate.wordpress.com/2012/04/09/%E6%B7%B1%E5%85%A5%E5%AD%A6%E4%B9%A0-cppcms/

 

CppCMS和Nginx协同工作

http://www.cnblogs.com/believeit/archive/2011/09/03/2183531.html

 

CppCMS支持文件上传

http://www.oschina.net/question/565065_66895

 

boost库学习随记五 Boost.Locale 之字符转换 gbkutf8 big5 string wstring等

http://blog.csdn.Net/leitianjun/article/details/24658655

 

How to Build libiconv with Microsoft VisualStudio

http://www.codeproject.com/Articles/302012/How-to-Build-libiconv-with-Microsoft-Visual-Studio

注意,IE6不支持JSON_RPC技术。

时间: 2024-08-22 15:13:16

HTTP服务端JSON服务端的相关文章

cxf-CXF动态生成client调用服务端,服务端收到参数为空,请教如何解决?

问题描述 CXF动态生成client调用服务端,服务端收到参数为空,请教如何解决? 请教大家一个问题. java做客户端,c#做服务端.java用apache.cxf的DynamicClientFactory或者JaxWsDynamicClientFactory根据wsdl生成client,调用服务端传递UserSyncData对象,服务端方法收到的参数对象是null,请问大家有解决办法吗?(需求:一定要用动态生成客户端的方式) 传递的对象UserSyncData 是jdk或者用cxf的wsdl

语言-安卓端访问服务端接口jsessionid失效怎么处理?

问题描述 安卓端访问服务端接口jsessionid失效怎么处理? 安卓端访问服务端接口,服务端语言groovy ,jsessionid失效怎么处理? 解决方案 http://bbs.csdn.net/topics/391071163

pc作为服务端,android端作为客户端,如何通过USB进行socket通信。

问题描述 pc作为服务端,android端作为客户端,如何通过USB进行socket通信. pc作为服务端,android端作为客户端,如何通过USB进行socket通信. 大概思路是什么

[原创图解]Win2003证书服务配置/客户端(服务端)证书申请/IIS站点SSL设置

[原创图解]Win2003证书服务配置/客户端(服务端)证书申请/IIS站点SSL设置 --欢迎转载,但转载请注明来自"菩提树下的杨过" 一.CA证书服务器安装   1.安装证书服务之前要先安装IIS服务并且保证"WEB服务扩展"中的"Active Server Pages"为允许状态      2.在"控制面板"中运行"添加或删除程序",切换到"添加/删除Windows组件"页   

印度虽然在高端IT服务方面力量强大,但相关费用也越来越高

中国人力成本的低廉使得印度来华"挖角"成为必然.因此,本地企业应为IT人才提供相应待遇,以免遭遇人才流失危机. 本报讯 (记者 陈莹报道) 近年来,印度软件企业纷纷加快了进军中国的步伐,并大规模招募中国软件人才.有业内人士分析认为,这一趋势在带动国内相关行业发展的同时,也应该引起本土IT服务企业的重视.本地企业应为IT人才提供相应待遇,以免遭遇人才流失危机. 多家企业加大在华投资 近日,印度软件巨头.第二大软件出口商Infosys科技公司表示,该公司计划在中国招聘6000名程序员,以满

Orange推出端到端云计算服务

本报讯 3月18日,全球整合通信网络和企业服务提供商OrangeBusinessSer-vices(简称Orange)宣布推出从基础设施到实时商务应用的端到端的云计算服务,通过"云就绪"网络,为企业提供更简单.安全.灵活的云服务. Orange中国区总经理李旭东表示:"未来30年,更多的中国企业将走出国门.只有他们在全球更多地方取得成功,中国经济才能得到更好的发展.云计算将在他们的全球化道路上发挥重要作用."Orange的云计算解决方案涵盖了一整套服务,包括从基础设

赶集网“一条龙服务” 可横跨PC端和移动端 有机会突出重围

中介交易 SEO诊断 淘宝客 云主机 技术大厅 [IT时代周刊观察]赶集网俨然在锻造一条让用户大到买房买车,小到转让二手商品的全套生活服务链,而这"一条龙服务",可以横跨PC端和移动端,24小时不离线,保持足够量的活跃用户,实现用户在平台上的流转,服务下沉至国内二三线城市,也会弥补之前一直被外界诟病的"业务层过薄,无法专注深入,在业务层面形成壁垒"的问题. 最近某媒体上发表了一篇标题为<尴尬赶集网,融资.上市.出售皆不易>的文章,文面说赶集网整体业绩虽然

AJAX依赖于符合预期的JSON服务 使用JSV和Dojo提高可靠性

这样做的一个好处是,您可以下载样例实用工具,帮助您编写自己的模式,并参照这些工具来验证对象. AJAX 应用程序依赖于符合预期的 JSON 服务.如果服务没有按预期的格式进行响应,或者使用无效的内容进行响应,则会发生意外行为.对于复杂应用程序,您可以通过实现自定义案例来验证服务响应,从而减轻发生意外行为的风险.另外,您还可以利用 JSON Schema 来验证输入. JSON Schema 是一种草案标准 (draft standard),它指定了一种基于 JSON 的格式来定义 JSON 数据

Java端和js端cookie跨域共享

问题描述 Java端和js端cookie跨域共享 关于cookie共享技术,查了网上的资料,有两种方式:后台服务端和前台js端. 我在网站A后台服务端设置cookie如下: Cookie cookie = new Cookie("mobile", "*****"); cookie.setPath("/"); cookie.setDomain("cms.ban.net"); response.addCookie(cookie);