PHP API 不能与 retrofit/gson 一起使用

PHP API not working in conjuntion with retrofit/gson

我无法让我的休息 API 处理来自我的 android 应用程序使用 retrofit/gson 的 POST 请求。支持 REST API 的是,接受非常基本的 JSON 解码,运行 一系列 SQL 查询,然后 return 格式化 JSON 数据返回到应用程序。

我知道问题不在于 API 逻辑,当我对传入的 JSON 数据进行硬编码或对 JSON 进行硬编码时,API 工作正常响应进入PHP。当我需要通过应用程序的 POST 请求传送 JSON 时,问题就开始了。我总是收到以下异常:FATAL EXCEPTION: DefaultDispatcher-worker-1FATAL EXCEPTION: DefaultDispatcher-worker-2 传入的 JSON 来自应用程序。

我已经尝试了 3 种接收传入的方式 JSON。第一个是使用 $jsonobj = http_get_request_body(); 函数,第二个是 $jsonobj = file_get_contents('php://input');,第三个是 $jsonobj = $_POST['code'];,最后一个很有趣。我不知道 ['here'] 中的内容是否重要或名称是什么,以便我可以使用它。我已经尝试更改这里的 ['text'] 几次,但没有成功。

在我们继续之前,这里是我的 PHP 脚本的概述。

//database config here.

if($_SERVER["REQUEST_METHOD"] == "POST"){
    //method of reciving JSON here.
    $obj = json_decode($jsonobj);

    //SQL logic here.
    echo json_encode($return);
}

如果不适用于 JSON 接收器,则此方法有效。

还有一个很好的机会,我什至根本没有发送 JSON,更不用说有效的 JSON。我知道有一些方法可以记录出站 JSON 但对于我来说,我无法让它们工作。所以在这里我将 post 位 android 代码。

我的API界面

interface API {
    @POST("posttest.php")
    suspend fun postit(@Body post: String): Phone
}

并且我在这种情况下使用了所述界面

val api = Retrofit.Builder()
            .baseUrl(BASE_URL)
            .addConverterFactory(GsonConverterFactory.create())
            .build()
            .create(API::class.java)

    GlobalScope.launch(Dispatchers.IO) {
        val response = api.postit(test)

        try {
               //logic
        }catch (e: Exception){
            //error handling
        }
    }

}

我想从房间数据库中提取 JSON,但我还没有这样做,所以我只是硬编码了 JSON;看起来像这样。

    private var test = "[\"text1\", \"text2\", \"text3\"]"

感谢您的宝贵时间。

以下代码仅用于与 API 建立应用程序连接。您将根据自己的需要调整其他所有内容(改造请求、响应、json 编码)

在 Android 应用程序中关注日志

我强烈建议您不要在没有数据验证的情况下查询数据库并使用PDO

最好为 api 使用一些 php 框架,例如 Slim、Laravel、Lumen

您可以POST请求最常用的类型之一:

  • application/x-www-form-urlencoded = 参数编码
  • application/json = 发送 json 数据 //用于您的案例
  • multipart/form-data = 图片等文件

你的 PHP 脚本应该是这样的

if($_SERVER["REQUEST_METHOD"] == "POST"){
    
    //TODO this is only example to get and return json data
    
    $jsonobj = file_get_contents('php://input');
    $json = json_decode($jsonobj);
    
    $response = array(
        "raw" => $jsonobj,
        "json" => $json
    );
    
    echo json_encode($response);
}else{
    //Send a 405 Method Not Allowed
    http_response_code(405);
    exit;
}

界面Api

interface API {
    @POST("posttest.php")
    suspend fun postIt(@Body requestBody: RequestBody): Response<ResponseBody>
}

和主要

val api = Retrofit.Builder()
                .baseUrl(BASE_URL)
                //.addConverterFactory(GsonConverterFactory.create())
                .build()
                .create(API::class.java);

        val test = "[\"text1\", \"text2\", \"text3\"]";  //hardcoded by you
        val requestBody = test.toRequestBody("application/json".toMediaTypeOrNull())

        GlobalScope.launch(Dispatchers.IO) {
            val response = api.postIt(requestBody)
            //withContext(Dispatchers.Main) {
                try {
                    if (response.isSuccessful) {
                        Log.i("RESPONSE", "DATA: " + response.body()?.string());
                    } else {
                        Log.i("RESPONSE", "ERROR: " + response.errorBody()?.string());
                    }

                    Log.i("RESPONSE", "RAW: " + response.raw());
                } catch (e: Exception) {
                    e.printStackTrace();
                    //error handling
                }
            //}
        }

原来问题出在我的 PHP API code 非常感谢 user:404438 @kylexy1357 给我日志代码所以我可以看到什么向上

他的code

val gson = GsonBuilder()
                .setLenient()
                .create()

  val builder = OkHttpClient().newBuilder()
        builder.readTimeout(120, TimeUnit.SECONDS)
        builder.connectTimeout(30, TimeUnit.SECONDS)

        if (BuildConfig.DEBUG) {
            val interceptor = HttpLoggingInterceptor()
            interceptor.level = HttpLoggingInterceptor.Level.BASIC
            builder.addInterceptor(interceptor)
        }
  val client = builder.build()


  val retrofit = Retrofit.Builder()
                .baseUrl(BASE_URL)
                .addConverterFactory(GsonConverterFactory.create(gson))
                .client(client)
                .build()