改造后请求错误 - 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<<JsonResponse>>
吗?
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+ 中崩溃)