改造后请求错误 - java.lang.IllegalStateException: 预期 BEGIN_OBJECT 但在第 1 行第 1 列路径 $

Posted

技术标签:

【中文标题】改造后请求错误 - java.lang.IllegalStateException: 预期 BEGIN_OBJECT 但在第 1 行第 1 列路径 $【英文标题】:Retrofit Post Request Error - java.lang.IllegalStateException: Expected BEGIN_OBJECT but was STRING at line 1 column 1 path $ 【发布时间】:2021-01-06 15:25:20 【问题描述】:

我正在尝试使用 Retrofit、MVVM、协程和 Hilt 发出发布请求。

发送帖子请求后,我收到此错误

java.lang.IllegalStateException:应为 BEGIN_OBJECT,但在第 1 行第 1 列路径 $

(我已经搜索过,但没有任何帮助)

AppModule

@Provides
@Singleton
fun provideRetrofit(gson: Gson) : Retrofit = Retrofit.Builder()
    .baseUrl(EndPoints.BASE_URL)
    .client(OkHttpClient.Builder().also  client ->
        if (BuildConfig.DEBUG)
            val logging = HttpLoggingInterceptor()
            logging.setLevel(HttpLoggingInterceptor.Level.BODY)
            client.addInterceptor(logging)
        
       .build()
    )
    .addConverterFactory(ScalarsConverterFactory.create())
    .addConverterFactory(GsonConverterFactory.create(gson))
    .build()

@Provides
@Singleton
fun provideApiService(retrofit: Retrofit) = retrofit.create(ApiService::class.java)

ApiService

@POST(EndPoints.REGISTER_WITH_EMAIL)
suspend fun registerUserWithEmail(@Body newUser: NewUser) : Response<JsonResponse>

ApiDataSource

suspend fun createNewUserEmail(newUser: NewUser) = apiService.registerUserWithEmail(newUser)

新用户

data class NewUser (
@SerializedName("username") val userName: String?,
@SerializedName("password") val password: String?,
@SerializedName("email") val email: String?,
@SerializedName("birthday") val birthday: String?,
@SerializedName("birth_year") val birthYear: String?,
@SerializedName("fullname") val fullname: String?,
@SerializedName("gender") val gender: String?)

注册回购

suspend fun saveUserWithEmail(newUser: NewUser) = safeApiCall  
apiDataSource.createNewUserEmail(newUser) 

注册视图模型

//SaveUserDetails

private val _saveDetailsEmail = MutableLiveData<Resource<JsonResponse>>()

fun doRegisterUserEmail(newUser: NewUser) = viewModelScope.launch 
    try 
        _saveDetailsEmail.value = registerRepo.saveUserWithEmail(newUser)
    
    catch (exception: Exception)

    

JsonResponse

data class JsonResponse (val success: String, val message: String)

注册片段

val userDetails = NewUser(usernameString, passwordPassed, emailPassed, birthdayPassed, birthYearPassed, fullnameString, genderString)
    registerViewModel.doRegisterUserEmail(userDetails)


    registerViewModel.saveDetailsEmail.observe(viewLifecycleOwner, Observer 
        when(it.status)
            Resource.Status.SUCCESS -> 
                if(it.data?.success == "0")
                    //Display error
                    Toast.makeText(requireContext(), it.data.message + "Registration", Toast.LENGTH_LONG ).show()
                
                else if(it.data?.success == "1")
                    //go to home activity
                    Toast.makeText(requireContext(), it.data.message + "Registrationx", Toast.LENGTH_LONG ).show()
                    val action  = DetailsFragmentDirections.actionDetailsFragmentToHomeActivity()
                    navController.navigate(action)
                
            
            Resource.Status.LOADING -> 
                //Show loading
            
            Resource.Status.ERROR -> 
                Toast.makeText(requireContext(), it.toString(), Toast.LENGTH_LONG).show()
            
        
    )


这是使用 POSTMAN 测试后的响应。它正在工作

"success":"1","message":"User details saved" 

更新RESOURCE类

data class Resource<out T>(val status: Status, val data: T?, val message: String?) 

enum class Status 
    SUCCESS,
    ERROR,
    LOADING



companion object 
    fun <T> success(data: T): Resource<T> 
        return Resource(Status.SUCCESS, data, null)
    

    fun <T> error(message: String, data: T? = null): Resource<T> 
        return Resource(Status.ERROR, data, message)
    

    fun <T> loading(data: T? = null): Resource<T> 
        return Resource(Status.LOADING, data, null)
    

更新 - 完整的 LOGCAT

    6:01.640 20137-20305/com.snappmi.snappmi I/okhttp.OkHttpClient: --> POST 
   https://2e3045dc760e.ngrok.io/snappmi/account/register/register_with_email.php
    09-20 14:26:01.640 20137-20305/com.snappmi.snappmi I/okhttp.OkHttpClient: Content-Type: application/json
    09-20 14:26:01.640 20137-20305/com.snappmi.snappmi I/okhttp.OkHttpClient: Content-Length: 150
    09-20 14:26:01.640 20137-20305/com.snappmi.snappmi I/okhttp.OkHttpClient: "birth_year":"1999","birthday":"1999-09-20","email":"makanaki@gmail.com","fullname":"makanaki","gender":"Male","password":"yellow","username":"maka"
    09-20 14:26:01.640 20137-20305/com.snappmi.snappmi I/okhttp.OkHttpClient: --> END POST (150-byte body)
    09-20 14:26:01.660 20137-20137/com.snappmi.snappmi W/DisplayListCanvas: DisplayListCanvas is started on unbinded RenderNode (without mOwningView)
    09-20 14:26:01.660 20137-20137/com.snappmi.snappmi W/DisplayListCanvas: DisplayListCanvas is started on unbinded RenderNode (without mOwningView)
    09-20 14:26:08.140 20137-20305/com.snappmi.snappmi I/okhttp.OkHttpClient: <-- 200 https://2e3045dc760e.ngrok.io/snappmi/account/register/register_with_email.php (6500ms)
    09-20 14:26:08.140 20137-20305/com.snappmi.snappmi I/okhttp.OkHttpClient: content-type: text/html; charset=UTF-8
    09-20 14:26:08.140 20137-20305/com.snappmi.snappmi I/okhttp.OkHttpClient: date: Sun, 20 Sep 2020 13:27:07 GMT
    09-20 14:26:08.140 20137-20305/com.snappmi.snappmi I/okhttp.OkHttpClient: server: Apache/2.4.43 (Win64) OpenSSL/1.1.1g PHP/7.4.6
    09-20 14:26:08.140 20137-20305/com.snappmi.snappmi I/okhttp.OkHttpClient: x-powered-by: PHP/7.4.6
    09-20 14:26:08.140 20137-20305/com.snappmi.snappmi I/okhttp.OkHttpClient: content-length: 1475
    09-20 14:26:08.150 20137-20305/com.snappmi.snappmi I/okhttp.OkHttpClient: <br />
    09-20 14:26:08.150 20137-20305/com.snappmi.snappmi I/okhttp.OkHttpClient: <b>Notice</b>:  Undefined index: username in <b>C:\xampp\htdocs\snappmi\account\register\register_with_email.php</b> on line <b>7</b><br />
    09-20 14:26:08.150 20137-20305/com.snappmi.snappmi I/okhttp.OkHttpClient: <br />
    09-20 14:26:08.150 20137-20305/com.snappmi.snappmi I/okhttp.OkHttpClient: <b>Notice</b>:  Undefined index: password in <b>C:\xampp\htdocs\snappmi\account\register\register_with_email.php</b> on line <b>8</b><br />
    09-20 14:26:08.150 20137-20305/com.snappmi.snappmi I/okhttp.OkHttpClient: <br />
    09-20 14:26:08.150 20137-20305/com.snappmi.snappmi I/okhttp.OkHttpClient: <b>Notice</b>:  Undefined index: email in <b>C:\xampp\htdocs\snappmi\account\register\register_with_email.php</b> on line <b>9</b><br />
    09-20 14:26:08.150 20137-20305/com.snappmi.snappmi I/okhttp.OkHttpClient: <br />
    09-20 14:26:08.150 20137-20305/com.snappmi.snappmi I/okhttp.OkHttpClient: <b>Notice</b>:  Undefined index: birthday in <b>C:\xampp\htdocs\snappmi\account\register\register_with_email.php</b> on line <b>10</b><br />
    09-20 14:26:08.150 20137-20305/com.snappmi.snappmi I/okhttp.OkHttpClient: <br />
    09-20 14:26:08.150 20137-20305/com.snappmi.snappmi I/okhttp.OkHttpClient: <b>Notice</b>:  Undefined index: birth_year in <b>C:\xampp\htdocs\snappmi\account\register\register_with_email.php</b> on line <b>11</b><br />
    09-20 14:26:08.150 20137-20305/com.snappmi.snappmi I/okhttp.OkHttpClient: <br />
    09-20 14:26:08.150 20137-20305/com.snappmi.snappmi I/okhttp.OkHttpClient: <b>Notice</b>:  Undefined index: fullname in <b>C:\xampp\htdocs\snappmi\account\register\register_with_email.php</b> on line <b>12</b><br />
    09-20 14:26:08.150 20137-20305/com.snappmi.snappmi I/okhttp.OkHttpClient: <br />
    09-20 14:26:08.150 20137-20305/com.snappmi.snappmi I/okhttp.OkHttpClient: <b>Notice</b>:  Undefined index: gender in <b>C:\xampp\htdocs\snappmi\account\register\register_with_email.php</b> on line <b>13</b><br />
    09-20 14:26:08.150 20137-20305/com.snappmi.snappmi I/okhttp.OkHttpClient: <br />
  

PHP 代码

if ($_SERVER['REQUEST_METHOD']=='POST')

 $username = $_POST['username'];
 $password = $_POST['password'];
 $email = $_POST['email'];
 $birthday = $_POST['birthday'];
 $birth_year = $_POST['birth_year'];
 $fullname = $_POST['fullname'];
 $gender = $_POST['gender'];
 $joined = date('Y/m/d H:i:s');
 $hashed_password = password_hash($password, PASSWORD_DEFAULT);

if(usernameExists($conn, $username))
 
     $result["success"] = "0";
     $result["message"] = "Username already taken";
     echo json_encode($result);
 

 elseif(!usernameExists($conn, $username))

      $sql = "INSERT INTO users (username, password, email, birthday, birth_year, fullname, gender, joined) VALUES (?,?,?,?,?,?,?,?)";

       $stmt= $conn->prepare($sql);
       $stmt->execute([$username, $hashed_password, $email, $birthday, $birth_year, $fullname, $gender, $joined]);

       if($stmt)
           $result["success"] = "1";
           $result["message"] = "success";
           echo json_encode($result);
       

 

 else

      $result["success"] = "0";
      $result["message"] = "An error occured" .mysqli_error($conn);

      echo json_encode($result);
 

【问题讨论】:

你能把整个日志贴出来吗? 其实这是唯一一个网络调用响应不成功抛出的Exception错误。 你能解释一下Resource&lt;&lt;JsonResponse&gt;&gt;吗? Resource 是一个有助于获取网络调用状态的类 - (成功、加载或错误)。因此,JsonResponse 由 Resource 包装,以进行正确的错误处理和了解状态。检查更新的问题。 @AdityaKurkure 在使用 okHttp 检查后,我得到了对从 android 中的 JSON 传递的所有值的不足索引。 完整性约束违规:1048 Column 'username' cannot be null in... 同时,JSON 在 LogCat 中很好地显示,但从行 content-type: text/htm - 未定义变量的错误是显示 【参考方案1】:

我必须解码发送到服务器的 JSON,尤其是当这里的内容类型是 application/json

$data = file_get_contents('php://input');
$json_data = json_decode($data , true);
//I added these above

if ($_SERVER['REQUEST_METHOD']=='POST')

 $username = $json_data["username"];
 $password = $json_data["password"];
 $email = $json_data["email"];


【讨论】:

以上是关于改造后请求错误 - java.lang.IllegalStateException: 预期 BEGIN_OBJECT 但在第 1 行第 1 列路径 $的主要内容,如果未能解决你的问题,请参考以下文章

Xposed出现 java.lang.IllegalAccessError: Class ref in pre-verified class resolved to unexpected imp(示例

致命异常:java.lang.IllegalStateException - 无法为 LinearLayout 创建层(仅在 Galaxy j4+、j6+ 中崩溃)

Android Studio“尚未附加片段”

Spring mvc 4.0.5 长轮询示例

HTTP 错误 400。请求主机名无效 - 改造

在改造中收到错误代码 400 错误请求,但适用于邮递员