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

Android/Kotlin retrofit2.adapter.rxjava2.HttpException: HTTP 415 Unsupported Media Type

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

时遇到了这个错误

retrofit2.adapter.rxjava2.HttpException: HTTP 415 Unsupported Media Type

完全不知道哪里错了
我已经按照 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>
}

我如何调用和处理我的请求 return:

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?

状态码4xx表示客户端发送的请求有错误;在这种特定情况下,415 表示服务器不支持您请求的 Content-Type。

检查您在代码中提供的 URL,服务器需要 application/json-patch+json MIME 类型,但您提供的是 application/x-www-form-urlencoded(这就是 @FormUrlEncoded 注释是为了).

要解决此问题,您应该更改 getUserLogin 方法以使用适当的 Content-Type(请参阅 this answer) and to send the appropriate JSON payload (see this answer,其中还告诉您如何设置自定义 header) .