258.Android Studio引入libcurl操作json

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"
    }]

截圖如下:

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章