libcurl是C++中对json操作的公开库,可以实现封装json打印数据,解析json数据,以及读取json中的数据
封装一个json
JNIEXPORT jboolean JNICALL Java_com_ldw_hello_BridgeUtils_reg
(JNIEnv * env, jobject obj, jstring jni_username, jstring jni_password, jstring jni_email, jstring jni_phone, jboolean jni_isDriver)
{
const char *username = env->GetStringUTFChars(jni_username, NULL);
const char *password = env->GetStringUTFChars(jni_password, NULL);
const char *email = env->GetStringUTFChars(jni_email, NULL);
const char *phone = env->GetStringUTFChars(jni_phone, NULL);
const char *isDriver = jni_isDriver==JNI_TRUE?"yes":"no";
/*
==== 给服务端的协议 ====
https://ip:port/reg [json_data]
{
username: "gailun",
password: "123123",
driver: "yes/no",
tel: "13331333333",
email: "danbing_at@163.cn",
id_card: "2104041222121211122"
}
*/
//将用户数据封装成一个json字符串
//(1)封装一个json字符串
char *post_str = NULL;
cJSON *root = cJSON_CreateObject();
cJSON_AddStringToObject(root, "username", username);
cJSON_AddStringToObject(root, "password", password);
cJSON_AddStringToObject(root, "email", email);
cJSON_AddStringToObject(root, "phone", phone);
cJSON_AddStringToObject(root, "isDriver", isDriver);
post_str = cJSON_Print(root);
cJSON_Delete(root);//释放root的空间
root = NULL;
__android_log_print(ANDROID_LOG_ERROR,TAG,"JNI-login: post_str = [%s]\n", post_str);
//释放资源
env->ReleaseStringUTFChars(jni_username, username);
env->ReleaseStringUTFChars(jni_password, password);
env->ReleaseStringUTFChars(jni_email, email);
env->ReleaseStringUTFChars(jni_phone, phone);
return JNI_TRUE;
}
向服务器发起请求
//(2) 想web服务器 发送http请求 其中post数据 json字符串
//1 设置curl url
curl_easy_setopt(curl, CURLOPT_URL, "http://101.200.190.150:7777/reg");
//2 开启post请求开关
curl_easy_setopt(curl, CURLOPT_POST, true);
//3 添加post数据
curl_easy_setopt(curl, CURLOPT_POSTFIELDS, post_str);
//4 设定一个处理服务器响应的回调函数,deal_response是回调函数
curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, deal_response);
//5 给回调函数传递一个形参
curl_easy_setopt(curl, CURLOPT_WRITEDATA, &responseData);
//6 向服务器发送请求,等待服务器的响应
res = curl_easy_perform(curl);
if (res != CURLE_OK) {
__android_log_print(ANDROID_LOG_ERROR,TAG,"JNI-login:perform ERROR, rescode= [%d]\n",
res);
return JNI_FALSE;
}
服务器返回数据并解析,返回给java层的数据
//(4) 解析服务器返回的json字符串
root = cJSON_Parse(responseData.data);
cJSON *result = cJSON_GetObjectItem(root, "result");
if(result && strcmp(result->valuestring, "ok") == 0) {
//注册成功
__android_log_print(ANDROID_LOG_ERROR,TAG,"JNI-login:login succ!!!");
return JNI_TRUE;
}
else {
//注册失败
cJSON* reason = cJSON_GetObjectItem(root, "reason");
if (reason) {
//已知错误
__android_log_print(ANDROID_LOG_ERROR,TAG,"JNI-login:login error, reason = %s!!!", reason->valuestring);
}
else {
//未知的错误
__android_log_print(ANDROID_LOG_ERROR,TAG,"JNI-login:login error, reason = Unknow!!!");
}
return JNI_FALSE;
}
完整代码如下:
//
// Created by Administrator on 2019/10/20.
//
#include <com_ldw_hello_BridgeUtils.h>
#include "curl/curl.h"
#include <android/log.h>
#include <cJSON.h>
#define TAG "JNI"
//默认服务器返回数据的长度
#define RESPONSE_DATA_LEN 4096
#ifdef __cplusplus
extern "C" {
#endif
//用来接收服务器一个buffer
typedef struct login_response_data
{
//构造函数
login_response_data() {
//分配空间
memset(data, 0, RESPONSE_DATA_LEN);
data_len = 0;
}
char data[RESPONSE_DATA_LEN];
int data_len;
}response_data_t;
//处理从服务器返回的数据ptr,将数据拷贝到arg中
size_t deal_response(void *ptr, size_t n, size_t m, void *arg)
{
int count = m*n;
response_data_t *response_data = (response_data_t*)arg;
memcpy(response_data->data, ptr, count);
response_data->data_len = count;
return response_data->data_len;
}
/*
* Class: com_ldw_hello_BridgeUtils
* Method: reg
* Signature: (Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Z)Z
*/
JNIEXPORT jboolean JNICALL Java_com_ldw_hello_BridgeUtils_reg
(JNIEnv * env, jobject obj, jstring jni_username, jstring jni_password, jstring jni_email, jstring jni_phone, jboolean jni_isDriver)
{
const char *username = env->GetStringUTFChars(jni_username, NULL);
const char *password = env->GetStringUTFChars(jni_password, NULL);
const char *email = env->GetStringUTFChars(jni_email, NULL);
const char *phone = env->GetStringUTFChars(jni_phone, NULL);
const char *isDriver = jni_isDriver==JNI_TRUE?"yes":"no";
char *post_str = NULL;
CURL* curl = NULL;//初始化一个curl指针
CURLcode res;//服务器返回的结果
response_data_t responseData;//专门用来存放从服务器返回的数据
curl = curl_easy_init();
if(curl == NULL){
__android_log_print(ANDROID_LOG_ERROR,TAG,"JNI-login: curl init error \n");
return JNI_FALSE;
}
/*
==== 给服务端的协议 ====
https://ip:port/reg [json_data]
{
username: "gailun",
password: "123123",
driver: "yes/no",
tel: "13331333333",
email: "danbing_at@163.cn",
id_card: "2104041222121211122"
}
*/
//将用户数据封装成一个json字符串
//(1)封装一个json字符串
cJSON *root = cJSON_CreateObject();
cJSON_AddStringToObject(root, "username", username);
cJSON_AddStringToObject(root, "password", password);
cJSON_AddStringToObject(root, "email", email);
cJSON_AddStringToObject(root, "phone", phone);
cJSON_AddStringToObject(root, "isDriver", isDriver);
post_str = cJSON_Print(root);
cJSON_Delete(root);//释放root的空间
root = NULL;
__android_log_print(ANDROID_LOG_ERROR,TAG,"JNI-login: post_str = [%s]\n", post_str);
//释放资源
env->ReleaseStringUTFChars(jni_username, username);
env->ReleaseStringUTFChars(jni_password, password);
env->ReleaseStringUTFChars(jni_email, email);
env->ReleaseStringUTFChars(jni_phone, phone);
/*
//(2) 想web服务器 发送http请求 其中post数据 json字符串
//1 设置curl url
curl_easy_setopt(curl, CURLOPT_URL, "http://101.200.190.150:7777/reg");
//2 开启post请求开关
curl_easy_setopt(curl, CURLOPT_POST, true);
//3 添加post数据
curl_easy_setopt(curl, CURLOPT_POSTFIELDS, post_str);
//4 设定一个处理服务器响应的回调函数,deal_response是回调函数
curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, deal_response);
//5 给回调函数传递一个形参
curl_easy_setopt(curl, CURLOPT_WRITEDATA, &responseData);
//6 向服务器发送请求,等待服务器的响应
res = curl_easy_perform(curl);
if (res != CURLE_OK) {
__android_log_print(ANDROID_LOG_ERROR,TAG,"JNI-login:perform ERROR, rescode= [%d]\n",
res);
return JNI_FALSE;
}
*/
//(3) 等待服务器的响应 此刻的responseData就是从服务器获取的数据
/*
//成功
{
result: "ok",
}
//失败
{
result: "error",
reason: "why...."
}
*
* */
//(4) 解析服务器返回的json字符串
/*
root = cJSON_Parse(responseData.data);
cJSON *result = cJSON_GetObjectItem(root, "result");
if(result && strcmp(result->valuestring, "ok") == 0) {
//注册成功
__android_log_print(ANDROID_LOG_ERROR,TAG,"JNI-login:login succ!!!");
return JNI_TRUE;
}
else {
//注册失败
cJSON* reason = cJSON_GetObjectItem(root, "reason");
if (reason) {
//已知错误
__android_log_print(ANDROID_LOG_ERROR,TAG,"JNI-login:login error, reason = %s!!!", reason->valuestring);
}
else {
//未知的错误
__android_log_print(ANDROID_LOG_ERROR,TAG,"JNI-login:login error, reason = Unknow!!!");
}
return JNI_FALSE;
}
*/
return JNI_TRUE;
}
#ifdef __cplusplus
}
#endif
输出端打印如下:
2019-10-20 13:18:46.999 28007-28007/com.ldw.hello E/JNI: JNI-login: post_str = [{
"username": "123123123",
"password": "asdasd",
"email": "fsgsdfgsdfg",
"phone": "546456456",
"isDriver": "yes"
}]
截图如下: