add query parameters map to handler method

This commit is contained in:
an-tao 2018-06-08 11:15:29 +08:00
parent beb7ae2b5d
commit fb6c6527bd
6 changed files with 55 additions and 9 deletions

View File

@ -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);
}

2
examples/static_link_example/api_v1_ApiTest.h Normal file → Executable file
View File

@ -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:

View File

@ -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<void (HttpResponse &)>&callback,int a,float b){
LOG_DEBUG<<"int a="<<a;

View File

@ -42,7 +42,7 @@ namespace drogon
virtual const std::string& path() const=0;
virtual Version getVersion() const=0;
virtual SessionPtr session() const=0;
virtual std::map<std::string,std::string > getPremeter() const=0;
virtual const std::map<std::string,std::string > & getParameters() const=0;
virtual ~HttpRequest(){}
};
}

View File

@ -81,7 +81,8 @@ namespace drogon
struct ApiBinder
{
std::string pathParameterPattern;
std::vector<int> parameterPlaces;
std::vector<size_t> parameterPlaces;
std::map<std::string,size_t> queryParametersPlaces;
HttpApiBinderBasePtr binderPtr;
std::vector<std::string> filtersName;
};
@ -135,10 +136,18 @@ void HttpAppFrameworkImpl::addApiPath(const std::string &path,
const std::vector<std::string> &filters)
{
//path will be like /api/v1/service/method/{1}/{2}/xxx...
std::vector<int> places;
std::vector<size_t> 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<std::string,size_t> 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="<<place<<") out of range (1 to "
<<binder->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<std::mutex> guard(_apiCtrlMutex);
_apiCtrlVector.push_back(std::move(_binder));
}
@ -391,6 +422,21 @@ void HttpAppFrameworkImpl::onAsyncRequest(const HttpRequest& req,const std::func
LOG_DEBUG<<"place="<<place<<" para:"<<params[place-1];
}
}
if(binder.queryParametersPlaces.size()>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<std::string> paraList;
for(auto p:params)
{

View File

@ -147,7 +147,7 @@ namespace drogon
// path_ = path;
// }
std::map<std::string,std::string > getPremeter() const override
const std::map<std::string,std::string > & getParameters() const override
{
return premeter_;
}