在上一篇文章中已经实现web服务,可以实现简单的http通信,但实现的功能还是单一的,即只实现了一个统一的入口,在实际项目中实现需要更加详细和复杂,如:
api 接口分类,类似/api/network/xxx 的请求则由network类进行处理,即通过/api/xxx查找对应的类xxx进行处理,而对应的处理类下又可以分很多方法,每个方法处理不同的事务,
这样可以达到处理模块清晰可见,维护起来更方便。
1,抽象类,实现保存路由与对象映射表
#ifndef __ICONTROLLER_H__
#define __ICONTROLLER_H__
#include <string>
#include <map>
#include <memory>
#include "json/json.h"
typedef void (*msgHandler)(Json::Value &response);
//消息处理回调控制类
class IController
{
public:
IController(const char *prefix);
~IController();
std::string const &getPrefix()const;
void virtual setup() = 0;
// 设置路由对应的回调函数
bool registerRoute(const char *method, const char *route, msgHandler handler);
void handle(const char *method, const char *route, Json::Value &response);
private:
std::string mPrefix;
std::map<std::string, msgHandler> mMsgHandlerMap; //处理函数映射表,不同的路径由不同的处理函数
};
typedef std::shared_ptr<IController> controllerPtr;
#endif
2,派生类实现setup接口,将路由与对象注册进来
#include <stdio.h>
#include <stdlib.h>
#include "networkAPI.h"
static void msgGetHandler(Json::Value &response);
static void msgPostHandler(Json::Value &response);
CNetworkAPI::CNetworkAPI(): IController("/api/network/")
{
}
CNetworkAPI::~CNetworkAPI()
{
}
void CNetworkAPI::setup()
{
//连起来就是: "/api/network/tcpip:GET" ----> msgGetHandler
if(!registerRoute("GET", "tcpip", msgGetHandler))
{
printf("register GET tcpip fail!\n");
}
//连起来就是: "/api/network/tcpip:POST" ----> msgPostHandler
if(!registerRoute("POST", "tcpip", msgPostHandler))
{
printf("register POST tcpip fail!\n");
}
}
void msgGetHandler(Json::Value &response)
{
response["code"] = "000000";
response["message"] = "success";
response["data"]["ipv4Addr"] = "192.168.1.8";
response["data"]["mask"] = "192.168.254.255";
response["data"]["gateway"] = "192.168.1.1";
response["data"]["mac"] = "00:33:44:9d:b3:00";
}
void msgPostHandler(Json::Value &response)
{
response["code"] = "000000";
response["message"] = "POST success";
printf("tcpip POST!\n");
}
3,webServer类进行统一管理
#ifndef __WEB_SERVER_H__
#define __WEB_SERVER_H__
#include "IController.h"
class CWebServer
{
public:
static CWebServer* instance();
//添加处理类
bool addController(controllerPtr controller);
//删除处理类
bool delController(std::string &key);
//根据key找到对应的处理类
controllerPtr getController(std::string &key);
private:
CWebServer();
~CWebServer();
private:
std::map<std::string, controllerPtr> mControllerMap; //路径与对象的映射表,如:["/api/network/"]=CNetworkAPI
typedef std::map<std::string, controllerPtr>::value_type mValueType;
typedef std::map<std::string, controllerPtr>::iterator iteratorType;
};
#endif
map表中保存着类似["/api/network/"]=CNetworkAPI的键-值对。即/api/network/的入口全部由类CNetworkAPI处理。
4,使用
//把处理类加到webServer里
void webStart()
{
std::shared_ptr<CNetworkAPI> network(new CNetworkAPI);
CWebServer::instance()->addController(network);
}
运行结果:
postman:
完整代码在: mongoose web服务