使用不上传的 jsonObject 改造 POST
Retrofit POST with jsonObject not uploading
我已经为此工作了几个小时,但没有取得任何进展。我是改造新手,基本上只是想用 jsonObject 发出一个简单的 post 请求,但收到此错误:
java.lang.illegalStateException: Expected BEGIN_OBJECT but was STRING at line
1 column 1 path $
我已经尝试将客户端代码的每一部分更改为使用 multipart 或 requestBody 甚至我的 php 代码,但没有任何效果,还尝试在脚本中回显输入,但它打印为空。非常感谢任何回复,谢谢。
界面
interface ApiInterface {
@Headers("Content-Type: application/json")
@POST(BuildConfig.URL_REGISTER)
fun signUpUser(@Body jsonObject: JSONObject): Call<Response>
}
回应
data class Response(@SerializedName("success") val success: Boolean,
@SerializedName("message") val message: String,
@SerializedName("userId") val userId:String)
客户端
class ApiClient {
private external fun register(): String
companion object {
// Used to load the 'native-lib' library on application startup.
init {
System.loadLibrary("native-lib")
}
}
private val okhttpClient = OkHttpClient.Builder().build()
private val gson: Gson = GsonBuilder()
.setLenient()
.create()
val instance: ApiInterface by lazy {
val retrofit = Retrofit.Builder()
.baseUrl(register())
.addConverterFactory(GsonConverterFactory.create(gson))
.client(okhttpClient)
.build()
retrofit.create(ApiInterface::class.java)
}
请求
val jsonObject = JSONObject()
jsonObject.put("username", username)
jsonObject.put("password", password)
jsonObject.put("email", email)
jsonObject.put("termsOfService", termsOfService)
jsonObject.put("profilePicPath", imagePath)
ApiClient().instance.signUpUser(jsonObject).enqueue(object: Callback<com.passionit.picnbuy.models.Response>{
override fun onFailure(
call: Call<com.passionit.picnbuy.models.Response>, t: Throwable) {
Toast.makeText(this@LoginOrSignUpActivity, t.message, Toast.LENGTH_LONG).show()
}
override fun onResponse(call: Call<com.passionit.picnbuy.models.Response>, response: Response<com.passionit.picnbuy.models.Response>) {
Toast.makeText(this@LoginOrSignUpActivity, response.message(), Toast.LENGTH_LONG).show()
if (response.body()!!.success) { //success, now uploading pfp
//successful response doing stuff...
} else {
//error caught in script file
}
}
})
Php 文件
<?php
$inputJSON = file_get_contents('php://input');
$input = json_decode($inputJSON, TRUE);
$conn = new mysqli("localhost", "root", "", "database");
if ($conn->connect_error) {
die("Failed to connect: " . $conn->connect_error);
}
$username = $input["username"];
$password = $input["password"];
$email = $input["email"];
$termsOfService = $input["termsOfService"];
$profilePicPath = $input["profilePicPath"];
//converting data
$termsOfService = $termsOfService ? 'true' : 'false';
//Username check
$usernameCheckQuery = $conn->prepare("SELECT * FROM allUsers WHERE username = ?");
$usernameCheckQuery->bind_param("s", $username);
$usernameCheckQuery->execute();
if ($usernameCheckQuery->num_rows > 0) {//username exists
$usernameCheckQuery->close();
print(json_encode(array('success' => false, 'message' => "username already exists")));
} else {
$usernameCheckQuery->close();
password_hash($password, PASSWORD_DEFAULT);
$query = $conn->prepare("INSERT INTO allUsers(username, password, email, tOS, pfPPath)
VALUES(?, ?, ?, ?, ?)");
$query->bind_param("sssss", $username, $password, $email, $termsOfService, $profilePicPath);
$query->execute();
$query->close();
print(json_encode(array('success' => true)));
}
$conn->close();
json_last_error();
?>
亲爱的朋友。
我建议将以下两行添加到 build.gradle 文件中。
// Logging Interceptor
implementation "com.squareup.okhttp3:logging-interceptor:4.7.2"
implementation 'org.conscrypt:conscrypt-android:2.4.0'
并如下图使用
object ApiServiceContainer {
private var apiService: ApiService? = null
fun getApiService(): ApiService {
if (apiService == null) {
val logging = HttpLoggingInterceptor()
logging.level = HttpLoggingInterceptor.Level.BODY
val httpClient = OkHttpClient.Builder()
httpClient.addInterceptor { chain ->
val original = chain.request()
val requestBuilder = original.newBuilder()
.header("Authorization", "Bearer " + token)
.header("Accept", "application/json")
.header("Content-Type", "application/json")
val request = requestBuilder.build()
chain.proceed(request)
}
httpClient.connectTimeout(30, TimeUnit.SECONDS)
httpClient.readTimeout(30, TimeUnit.SECONDS)
httpClient.addNetworkInterceptor(logging)
val okHttpClient = httpClient.build()
val gson = GsonBuilder()
.setLenient()
.create()
val retrofit = Retrofit.Builder()
.baseUrl(EndPoints.API_BASE_URL)
.addConverterFactory(
GsonConverterFactory.create(gson)
)
.addCallAdapterFactory(RxJava2CallAdapterFactory.create())
.client(okHttpClient)
.build()
apiService = retrofit.create(ApiService::class.java)
}
return apiService!!
}
所以你可以看到服务器发出的错误。
我发现在 php 中收到时,无论出于何种原因,发送数组或字段以外的任何内容都会添加额外的字符,我最终只使用了这样的字段。
interface ApiInterface {
@FormUrlEncoded
@POST(BuildConfig.URL_REGISTER)
fun signUpUser(@Field("username") username: String,
@Field("password") password: String,
@Field("email") email: String,
@Field("termsOfService") termsOfService: Boolean,
@Field("profilePicPath") profilePicPath: String): Call<Response>
}
并且在 php 中收到的是这样的
$username = $_POST['username'];
$password = $_POST['password'];
$email = $_POST['email'];
$termsOfService = $_POST['termsOfService'];
$profilePicPath = $_POST['profilePicPath'];
我已经为此工作了几个小时,但没有取得任何进展。我是改造新手,基本上只是想用 jsonObject 发出一个简单的 post 请求,但收到此错误:
java.lang.illegalStateException: Expected BEGIN_OBJECT but was STRING at line
1 column 1 path $
我已经尝试将客户端代码的每一部分更改为使用 multipart 或 requestBody 甚至我的 php 代码,但没有任何效果,还尝试在脚本中回显输入,但它打印为空。非常感谢任何回复,谢谢。
界面
interface ApiInterface {
@Headers("Content-Type: application/json")
@POST(BuildConfig.URL_REGISTER)
fun signUpUser(@Body jsonObject: JSONObject): Call<Response>
}
回应
data class Response(@SerializedName("success") val success: Boolean,
@SerializedName("message") val message: String,
@SerializedName("userId") val userId:String)
客户端
class ApiClient {
private external fun register(): String
companion object {
// Used to load the 'native-lib' library on application startup.
init {
System.loadLibrary("native-lib")
}
}
private val okhttpClient = OkHttpClient.Builder().build()
private val gson: Gson = GsonBuilder()
.setLenient()
.create()
val instance: ApiInterface by lazy {
val retrofit = Retrofit.Builder()
.baseUrl(register())
.addConverterFactory(GsonConverterFactory.create(gson))
.client(okhttpClient)
.build()
retrofit.create(ApiInterface::class.java)
}
请求
val jsonObject = JSONObject()
jsonObject.put("username", username)
jsonObject.put("password", password)
jsonObject.put("email", email)
jsonObject.put("termsOfService", termsOfService)
jsonObject.put("profilePicPath", imagePath)
ApiClient().instance.signUpUser(jsonObject).enqueue(object: Callback<com.passionit.picnbuy.models.Response>{
override fun onFailure(
call: Call<com.passionit.picnbuy.models.Response>, t: Throwable) {
Toast.makeText(this@LoginOrSignUpActivity, t.message, Toast.LENGTH_LONG).show()
}
override fun onResponse(call: Call<com.passionit.picnbuy.models.Response>, response: Response<com.passionit.picnbuy.models.Response>) {
Toast.makeText(this@LoginOrSignUpActivity, response.message(), Toast.LENGTH_LONG).show()
if (response.body()!!.success) { //success, now uploading pfp
//successful response doing stuff...
} else {
//error caught in script file
}
}
})
Php 文件
<?php
$inputJSON = file_get_contents('php://input');
$input = json_decode($inputJSON, TRUE);
$conn = new mysqli("localhost", "root", "", "database");
if ($conn->connect_error) {
die("Failed to connect: " . $conn->connect_error);
}
$username = $input["username"];
$password = $input["password"];
$email = $input["email"];
$termsOfService = $input["termsOfService"];
$profilePicPath = $input["profilePicPath"];
//converting data
$termsOfService = $termsOfService ? 'true' : 'false';
//Username check
$usernameCheckQuery = $conn->prepare("SELECT * FROM allUsers WHERE username = ?");
$usernameCheckQuery->bind_param("s", $username);
$usernameCheckQuery->execute();
if ($usernameCheckQuery->num_rows > 0) {//username exists
$usernameCheckQuery->close();
print(json_encode(array('success' => false, 'message' => "username already exists")));
} else {
$usernameCheckQuery->close();
password_hash($password, PASSWORD_DEFAULT);
$query = $conn->prepare("INSERT INTO allUsers(username, password, email, tOS, pfPPath)
VALUES(?, ?, ?, ?, ?)");
$query->bind_param("sssss", $username, $password, $email, $termsOfService, $profilePicPath);
$query->execute();
$query->close();
print(json_encode(array('success' => true)));
}
$conn->close();
json_last_error();
?>
亲爱的朋友。 我建议将以下两行添加到 build.gradle 文件中。
// Logging Interceptor
implementation "com.squareup.okhttp3:logging-interceptor:4.7.2"
implementation 'org.conscrypt:conscrypt-android:2.4.0'
并如下图使用
object ApiServiceContainer {
private var apiService: ApiService? = null
fun getApiService(): ApiService {
if (apiService == null) {
val logging = HttpLoggingInterceptor()
logging.level = HttpLoggingInterceptor.Level.BODY
val httpClient = OkHttpClient.Builder()
httpClient.addInterceptor { chain ->
val original = chain.request()
val requestBuilder = original.newBuilder()
.header("Authorization", "Bearer " + token)
.header("Accept", "application/json")
.header("Content-Type", "application/json")
val request = requestBuilder.build()
chain.proceed(request)
}
httpClient.connectTimeout(30, TimeUnit.SECONDS)
httpClient.readTimeout(30, TimeUnit.SECONDS)
httpClient.addNetworkInterceptor(logging)
val okHttpClient = httpClient.build()
val gson = GsonBuilder()
.setLenient()
.create()
val retrofit = Retrofit.Builder()
.baseUrl(EndPoints.API_BASE_URL)
.addConverterFactory(
GsonConverterFactory.create(gson)
)
.addCallAdapterFactory(RxJava2CallAdapterFactory.create())
.client(okHttpClient)
.build()
apiService = retrofit.create(ApiService::class.java)
}
return apiService!!
}
所以你可以看到服务器发出的错误。
我发现在 php 中收到时,无论出于何种原因,发送数组或字段以外的任何内容都会添加额外的字符,我最终只使用了这样的字段。
interface ApiInterface {
@FormUrlEncoded
@POST(BuildConfig.URL_REGISTER)
fun signUpUser(@Field("username") username: String,
@Field("password") password: String,
@Field("email") email: String,
@Field("termsOfService") termsOfService: Boolean,
@Field("profilePicPath") profilePicPath: String): Call<Response>
}
并且在 php 中收到的是这样的
$username = $_POST['username'];
$password = $_POST['password'];
$email = $_POST['email'];
$termsOfService = $_POST['termsOfService'];
$profilePicPath = $_POST['profilePicPath'];