我只是从Retrofit
开始,而我在尝试制作一个简单的POST request
retrofit2.adapter.rxjava2.HttpException:HTTP 415不支持的媒体 输入
我根本不知道哪里出了错。
我已遵循此tutorial来实现Retrofit
和RxJava
。
我的RetrofitClient
实现了我的OkHttpClient
:
object RetrofitClient {
private const val CONNECTION_TIMEOUT: Long = 60
private val BASE_URL = "https://pictalio-dev.azurewebsites.net/api/"
private var retrofit: Retrofit? = null
fun getClient(token: String): Retrofit {
if (retrofit == null) {
retrofit = Retrofit.Builder()
.baseUrl(BASE_URL)
.addConverterFactory(GsonConverterFactory.create())
.addCallAdapterFactory(RxJava2CallAdapterFactory.create())
.client(getOkHttpClient(token))
.build()
}
return retrofit!!
}
private fun getOkHttpClient(token: String): OkHttpClient {
val okClientBuilder = OkHttpClient.Builder()
val httpLoggingInterceptor = HttpLoggingInterceptor()
okClientBuilder.addInterceptor { chain ->
val original = chain.request()
val requestBuilder = original.newBuilder()
.header("Authorization", token)
val request = requestBuilder.build()
chain.proceed(request)
}
httpLoggingInterceptor.level = HttpLoggingInterceptor.Level.BASIC
okClientBuilder.addInterceptor(httpLoggingInterceptor)
okClientBuilder.connectTimeout(CONNECTION_TIMEOUT, TimeUnit.SECONDS)
okClientBuilder.readTimeout(CONNECTION_TIMEOUT, TimeUnit.SECONDS)
okClientBuilder.writeTimeout(CONNECTION_TIMEOUT, TimeUnit.SECONDS)
return okClientBuilder.build()
}
}
有我的ApiService
:
interface ApiService {
@FormUrlEncoded
@POST("account/login")
fun getUserLogin(
@Field("email") email: String,
@Field("password") password: String
): Single<User>
}
以下是我如何处理和处理请求返回的信息:
class SignInActivity : AppCompatActivity(), View.OnClickListener, RequestSignIn.sendDataResponse, RequestGetUser.sendDataResponse {
private var user: User? = null
private var pDialog: SweetAlertDialog? = null
lateinit var emailEditText: EditText
lateinit var passwordEditText: EditText
var persistentUser: PersistentUser? = null
//Initialization of disposable
private val disposable = CompositeDisposable()
private lateinit var apiService: ApiService
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.signin_activity)
emailEditText = findViewById(R.id.email)
passwordEditText = findViewById(R.id.password)
//Initialization of apiService
apiService = RetrofitClient.getClient("").create(ApiService::class.java)
}
override fun onClick(v: View) {
val email: EditText
val password: EditText
email = findViewById(R.id.email)
password = findViewById(R.id.password)
R.id.login -> {
if (Tools.isValidEmail(email.text.toString())) {
disposable.add(apiService.getUserLogin(email.text.toString(), password.text.toString())
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe({ user ->
pDialog!!.dismissWithAnimation()
Log.e("USER", "token: " + user.token)
}, Throwable::printStackTrace)
)
} else {
Toast.makeText(this@SignInActivity, getString(R.string.enter_valid_email), Toast.LENGTH_SHORT).show()
//emailnotvalid
}
}
}
}
override fun onDestroy() {
super.onDestroy()
disposable.dispose()
}
}
任何帮助将不胜感激。
编辑:
我已删除@FormUrlEncoded
并添加了.header("Content-Type", "application/json")
,我现在将JSONObject
作为Body
发送如下:
disposable.add(apiService.getUserLogin(JSONObject(map)))
但是我的服务器上有一个400 BAD REQUEST
。
我什至将ScalarsConverter
添加到了RetrofitClient
中。
.addConverterFactory(ScalarsConverterFactory.create())
所以我尝试使用RequestBody
如下
fun getUserLogin(@Body requestBody: String): Single<User>
disposable.add(apiService.getUserLogin(RequestBody.create(MediaType.parse("application/json"), JSONObject(map).toString())) .
它也很好!我该如何简单地发送JSONObject
而不是每次创建一个RequestBody
?
答案 0 :(得分:1)
状态代码4xx表示客户端发送的请求中存在错误;在这种特定情况下415表示服务器不支持您请求的Content-Type。
检查您在代码中提供的URL,服务器期望使用application/json-patch+json
MIME类型,但是您提供的是application/x-www-form-urlencoded
(这就是@FormUrlEncoded
注释的含义)。
要解决此问题,您应该更改getUserLogin
方法以使用适当的Content-Type(请参阅this answer)并发送适当的JSON有效负载(请参阅this answer,该方法还告诉您如何设置自定义标头)。