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: "[email protected]",
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: "[email protected]",
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"
}]
截圖如下: