From fb6c6527bdc9dcf8745835eefba5001adb101014 Mon Sep 17 00:00:00 2001 From: an-tao <20741618@qq.com> Date: Fri, 8 Jun 2018 11:15:29 +0800 Subject: [PATCH] add query parameters map to handler method --- examples/static_link_example/ListParaCtl.cc | 2 +- examples/static_link_example/api_v1_ApiTest.h | 2 +- examples/static_link_example/main.cc | 2 +- lib/inc/drogon/HttpRequest.h | 2 +- lib/src/HttpAppFramework.cc | 54 +++++++++++++++++-- lib/src/HttpRequestImpl.h | 2 +- 6 files changed, 55 insertions(+), 9 deletions(-) mode change 100644 => 100755 examples/static_link_example/api_v1_ApiTest.h diff --git a/examples/static_link_example/ListParaCtl.cc b/examples/static_link_example/ListParaCtl.cc index c8f82215..ed78614f 100755 --- a/examples/static_link_example/ListParaCtl.cc +++ b/examples/static_link_example/ListParaCtl.cc @@ -4,7 +4,7 @@ void ListParaCtl::asyncHandleHttpRequest(const HttpRequest& req,const std::funct //write your application logic here HttpViewData data; data.insert("title",std::string("list parameters")); - data.insert("parameters",req.getPremeter()); + data.insert("parameters",req.getParameters()); auto res=drogon::HttpResponse::newHttpViewResponse("ListParaView.csp",data); callback(*res); } \ No newline at end of file diff --git a/examples/static_link_example/api_v1_ApiTest.h b/examples/static_link_example/api_v1_ApiTest.h old mode 100644 new mode 100755 index 062b2daf..b5859fc5 --- a/examples/static_link_example/api_v1_ApiTest.h +++ b/examples/static_link_example/api_v1_ApiTest.h @@ -10,7 +10,7 @@ namespace api METHOD_LIST_BEGIN //use METHOD_ADD to add your custom processing function here; METHOD_ADD(ApiTest::get,"/{2}/{1}",1,"drogon::GetFilter");//path will be /api/v1/ApiTest/get/{arg2}/{arg1} - METHOD_ADD(ApiTest::your_method_name,"/{1}/{2}/list",0,"drogon::GetFilter");//path will be /api/v1/ApiTest/{arg1}/{arg2}/list + METHOD_ADD(ApiTest::your_method_name,"/{1}/list?p2={2}",0,"drogon::GetFilter");//path will be /api/v1/ApiTest/{arg1}/list METHOD_LIST_END //your declaration of processing function maybe like this: diff --git a/examples/static_link_example/main.cc b/examples/static_link_example/main.cc index 78c2075e..8092e25c 100755 --- a/examples/static_link_example/main.cc +++ b/examples/static_link_example/main.cc @@ -86,7 +86,7 @@ int main() drogon::HttpAppFramework::instance().addListener("0.0.0.0",8080); trantor::Logger::setLogLevel(trantor::Logger::TRACE); //class function - drogon::HttpAppFramework::registerHttpApiMethod("/api/v1/handle1/{1}/{2}/{3}/{4}",&A::handle); + drogon::HttpAppFramework::registerHttpApiMethod("/api/v1/handle1/{1}/{2}/?p3={3}&p4={4}",&A::handle); //lambda example drogon::HttpAppFramework::registerHttpApiMethod("/api/v1/handle2/{1}/{2}",[](const HttpRequest&req,const std::function&callback,int a,float b){ LOG_DEBUG<<"int a="< getPremeter() const=0; + virtual const std::map & getParameters() const=0; virtual ~HttpRequest(){} }; } \ No newline at end of file diff --git a/lib/src/HttpAppFramework.cc b/lib/src/HttpAppFramework.cc index f5e19d4a..4989f1c3 100755 --- a/lib/src/HttpAppFramework.cc +++ b/lib/src/HttpAppFramework.cc @@ -81,7 +81,8 @@ namespace drogon struct ApiBinder { std::string pathParameterPattern; - std::vector parameterPlaces; + std::vector parameterPlaces; + std::map queryParametersPlaces; HttpApiBinderBasePtr binderPtr; std::vector filtersName; }; @@ -135,10 +136,18 @@ void HttpAppFrameworkImpl::addApiPath(const std::string &path, const std::vector &filters) { //path will be like /api/v1/service/method/{1}/{2}/xxx... - std::vector places; + std::vector places; std::string tmpPath=path; - std::regex regex=std::regex("\\{([0-9]*)\\}"); + std::string paras=""; + std::regex regex=std::regex("\\{([0-9]+)\\}"); std::smatch results; + auto pos=tmpPath.find("?"); + if(pos!=std::string::npos) + { + paras=tmpPath.substr(pos+1); + tmpPath=tmpPath.substr(0,pos); + } + std::string originPath=tmpPath; while(std::regex_search(tmpPath,results,regex)) { if(results.size()>1) @@ -154,11 +163,33 @@ void HttpAppFrameworkImpl::addApiPath(const std::string &path, } tmpPath=results.suffix(); } + std::map parametersPlaces; + if(!paras.empty()) + { + + std::regex pregex("([^&]*)=\\{([0-9]+)\\}&*"); + while(std::regex_search(paras,results,pregex)) + { + if(results.size()>2) + { + size_t place=(size_t)std::stoi(results[2].str()); + if(place>binder->paramCount()||place==0) + { + LOG_ERROR<<"parameter placeholder(value="<paramCount()<<")"; + exit(0); + } + parametersPlaces[results[1].str()]=place; + } + paras=results.suffix(); + } + } struct ApiBinder _binder; _binder.parameterPlaces=std::move(places); + _binder.queryParametersPlaces=std::move(parametersPlaces); _binder.binderPtr=binder; _binder.filtersName=filters; - _binder.pathParameterPattern=std::regex_replace(path,regex,"([^/]*)"); + _binder.pathParameterPattern=std::regex_replace(originPath,regex,"([^/]*)"); std::lock_guard guard(_apiCtrlMutex); _apiCtrlVector.push_back(std::move(_binder)); } @@ -391,6 +422,21 @@ void HttpAppFrameworkImpl::onAsyncRequest(const HttpRequest& req,const std::func LOG_DEBUG<<"place="<0) + { + auto qureyPara=req.getParameters(); + for(auto parameter:qureyPara) + { + if(binder.queryParametersPlaces.find(parameter.first)!= + binder.queryParametersPlaces.end()) + { + auto place=binder.queryParametersPlaces[parameter.first]; + if(place>params.size()) + params.resize(place); + params[place-1]=parameter.second; + } + } + } std::list paraList; for(auto p:params) { diff --git a/lib/src/HttpRequestImpl.h b/lib/src/HttpRequestImpl.h index 00e0f3b4..1db07f40 100755 --- a/lib/src/HttpRequestImpl.h +++ b/lib/src/HttpRequestImpl.h @@ -147,7 +147,7 @@ namespace drogon // path_ = path; // } - std::map getPremeter() const override + const std::map & getParameters() const override { return premeter_; }