最近在写微服务相关的东西,微服务对外公布的rest api如何让不同语言的开发者方便调用呢?本文简单实现了个rest接口客户端调用库,可简单满足vc、qt、java开发者通过指定网关及其代理的微服务名访问具体的rest接口的需求。
vc
vc下用的是大名鼎鼎的libcurl库封装rest调用,libcurl怎么用vc编译看上一篇文章,下面直接上代码吧
restcli.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
using namespace std;
class RestClient
{
public:
RestClient();
RestClient(string address, int port, string serviceName);
void SetAuth(string appKey, string appSecret);
void SetTimeout(int connTimeout, int timeout);
bool Get(string path, string &result);
bool Post(string path, string &result, string postData="");
protected:
void genBasePath();
void genAuthParam();
string getUrl(string path);
private:
string address;
int port;
string serviceName;
string appKey;
string appSecret;
int connTimeout;
int timeout;
string basePath;
string authParam;
};
restcli.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
static int writer(char *data, size_t size, size_t nmemb, std::string *writerData)
{
if(writerData == NULL)
return 0;
writerData->append(data, size*nmemb);
return size * nmemb;
}
RestClient::RestClient()
{
this->address = "localhost";
this->port = 80;
this->serviceName = "";
this->appKey = "";
this->appSecret = "";
this->connTimeout = -1;
this->timeout = -1;
genBasePath();
genAuthParam();
}
RestClient::RestClient(string address, int port, string serviceName)
{
this->address = address;
this->port = port;
this->serviceName = serviceName;
this->appKey = "";
this->appSecret = "";
this->connTimeout = -1;
this->timeout = -1;
genBasePath();
genAuthParam();
}
void RestClient::genBasePath()
{
ostringstream osPort;
osPort<<this->port;
this->basePath = "http://" + this->address + ":" + osPort.str() + "/";
if (this->serviceName.size() > 0)
this->basePath += this->serviceName + string("/");
}
void RestClient::genAuthParam()
{
if (appKey.size() > 0) {
authParam = "appKey=" + appKey + "&appSecret=" + appSecret;
}
}
string RestClient::getUrl(string path)
{
string url = basePath + path;
if (authParam.size() == 0)
return url;
int pos = path.find("?");
if (pos >= 0) {
url += "&" + authParam;
} else {
url += "?" + authParam;
}
return url;
}
void RestClient::SetAuth(string appKey, string appSecret)
{
this->appKey = appKey;
this->appSecret = appSecret;
}
void RestClient::SetTimeout(int connTimeout, int timeout)
{
this->connTimeout = connTimeout;
this->timeout = timeout;
}
bool RestClient::Get(string path, string &result)
{
CURLcode code;
CURL* curl = curl_easy_init();
if (curl == NULL)
return false;
string url = getUrl(path);
curl_easy_setopt(curl, CURLOPT_URL, url.c_str());
curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, writer);
curl_easy_setopt(curl, CURLOPT_WRITEDATA, &result);
curl_easy_setopt(curl, CURLOPT_NOSIGNAL, 1);
curl_easy_setopt(curl, CURLOPT_CONNECTTIMEOUT, this->connTimeout);
curl_easy_setopt(curl, CURLOPT_TIMEOUT, this->timeout);
code = curl_easy_perform(curl);
curl_easy_cleanup(curl);
if(code != CURLE_OK)
return false;
return true;
}
bool RestClient::Post(string path, string &result, string postData)
{
CURLcode code;
CURL* curl = curl_easy_init();
if (curl == NULL)
return false;
curl_easy_setopt(curl, CURLOPT_URL, getUrl(path).c_str());
curl_easy_setopt(curl, CURLOPT_POST, 1);
curl_easy_setopt(curl, CURLOPT_POSTFIELDS, postData.c_str());
curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, writer);
curl_easy_setopt(curl, CURLOPT_WRITEDATA, &result);
curl_easy_setopt(curl, CURLOPT_NOSIGNAL, 1);
curl_easy_setopt(curl, CURLOPT_CONNECTTIMEOUT, this->connTimeout);
curl_easy_setopt(curl, CURLOPT_TIMEOUT, this->timeout);
code = curl_easy_perform(curl);
curl_easy_cleanup(curl);
if(code != CURLE_OK)
return false;
return true;
}
qt
之所以用libcurl进行http请求处理的一个重要原因就是为了想在vc下和qt下可以复用一套代码,所以qt的代码和vc的是一样的。具体qt的工程文件x.pro
怎么写见上一篇文章
java
java处理http请求就简单多了,如果是springMVC工程下直接用个restTemplate就完成了,下面还是用java下最普遍使用的httpclient库实现。我建立maven工程,引入httpclient依赖4.5.5
1 | public class RestClient { |
建maven工程的一个重要原因是想封装的rest访问库只要提供一个jar包就可以,如果普通工程恐怕要附带提供其他如httpclient.jar的包。~标记一下以后写maven的文章~
参考文章
*下面这些文章是我写上面这些时看过的,记录下来以备后看
libcurl
- https://curl.haxx.se/libcurl/c/libcurl-tutorial.html
- https://blog.csdn.net/mao834099514/article/details/54947853
- https://blog.csdn.net/lijinqi1987/article/details/53925835
- https://www.cnblogs.com/jikexianfeng/p/6055024.html
- https://www.cnblogs.com/lidabo/p/4583061.html
- https://blog.csdn.net/ilovec1/article/details/52039672
- https://blog.csdn.net/educast/article/details/47099607
qt
httpclient