Android /科特林retrofit2.adapter.rxjava2.HttpException:HTTP 415不支持的媒体类型

时间:2019-06-26 14:17:51

标签: android kotlin retrofit2 rx-java2 okhttp3

我只是从Retrofit开始,而我在尝试制作一个简单的POST request

时遇到了这个错误
  

retrofit2.adapter.rxjava2.HttpException:HTTP 415不支持的媒体   输入

我根本不知道哪里出了错。
我已遵循此tutorial来实现RetrofitRxJava

我的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

1 个答案:

答案 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,该方法还告诉您如何设置自定义标头)。