【问题标题】:Generic function to make post request in Volley在 Volley 中发出 post 请求的通用函数
【发布时间】:2019-08-02 07:59:24
【问题描述】:

我正在开发一个 android 应用程序,我想制作一个通用的 volley post request 函数,我将我的函数编写如下:

 public fun <T> push(context: Context, url: String, myObject: T, completion: (response: String) -> Unit) {
        val queue = Volley.newRequestQueue(context)
        val sr = object : StringRequest(
            Method.POST, url,
            Response.Listener { response ->
                println(response)
                completion(response)
            },
            Response.ErrorListener { volleyError ->
                Common.showVolleyError(volleyError, context)
            }) {
            override fun getParams(): Map<String, String> {
                val params = myObject as HashMap<String, String>
                return params
            }

            @Throws(AuthFailureError::class)
            override fun getHeaders(): Map<String, String> {
                val params = HashMap<String, String>()
                params["Content-Type"] = "application/x-www-form-urlencoded"
                params["X-Requested-With"] = "XMLHttpRequest"
                return params
            }
        }

        sr.retryPolicy = DefaultRetryPolicy(
            0,
            DefaultRetryPolicy.DEFAULT_MAX_RETRIES,
            DefaultRetryPolicy.DEFAULT_BACKOFF_MULT
        )
        queue.add(sr)
    }

我强制执行的是如何将我的可序列化对象转换为HashMap&lt;String, String&gt;(),即如何将myObject 绑定到getParams() 函数,

【问题讨论】:

  • 你的 api 是否需要一个 json 正文来发送请求?
  • 我的 API 接收正文为 application/x-www-form-urlencode

标签: java android generics kotlin android-volley


【解决方案1】:

使基类包含一个抽象方法返回Map&lt;String, String&gt;,例如getConvertedParams。此方法应将自身转换为Map&lt;String, String&gt;,例如:

val params = HashMap<String, String>()
params["attribute1"] = attribute1
params["attribute2"] = attribute2
...
return params

每个请求对象都应该扩展该基类并覆盖该方法。在您发送请求的getParams 中,为您的通用请求对象调用getConvertedParams

override fun getParams(): Map<String, String> {
   val params = myObject.getConvertedParams()
   return params
}

也不要忘记更改方法签名

public fun <BaseClassName> push(context: Context, url: String, myObject: BaseClassName, completion: (response: String) -> Unit)

【讨论】:

  • 我知道这种方式,但我想要一种将任何可序列化对象转换为 HashMap&lt;String, String&gt;() 的方法
  • 你看过thisthisthis吗?如果你有,他们没有工作吗?
【解决方案2】:

最后对于任何可能喜欢使用这种方式的人,我重写了如下函数:

public fun <T> push(context: Context, url: String, myObject: T,myObjectType : Array<Field>, completion: (response: String) -> Unit) {

    val myObjectAsDict = HashMap<String, String>()
    val allFields = myObjectType //:Array<Field> = myObjectType!!::class.java.declaredFields
    for ( field in allFields) {
        if (!field.isAccessible) {
            field.isAccessible = true
        }


        val value = field.get(myObject)
        if (value != null)
        {
            if( field.name != "serialVersionUID") {
                myObjectAsDict[field.name] = value.toString()
            }
        }
    }

    println(myObjectAsDict)

    val queue = Volley.newRequestQueue(context)
    val sr = object : StringRequest(
        Method.POST, url,
        Response.Listener { response ->
            println(response)
            completion(response)
        },
        Response.ErrorListener { volleyError ->
            Common.showVolleyError(volleyError, context)
        }) {

        override fun getParams(): Map<String, String> {
            val params = myObjectAsDict
            return params
        }

        @Throws(AuthFailureError::class)
        override fun getHeaders(): Map<String, String> {
            val params = HashMap<String, String>()
            params["Content-Type"] = "application/x-www-form-urlencoded"
            params["X-Requested-With"] = "XMLHttpRequest"
            return params
        }
    }

    sr.retryPolicy = DefaultRetryPolicy(
        0,
        DefaultRetryPolicy.DEFAULT_MAX_RETRIES,
        DefaultRetryPolicy.DEFAULT_BACKOFF_MULT
    )
    queue.add(sr)
}

并使用如下:

 var myClass = MyClass()
        VolleyFunctions.push(this,"URL",myClass, MyClass::class.java.declaredFields)
        {
                response->
            myClass = Gson().fromJson(response, MyClass::class.java)
            println("myClass.Name${myClass.name}")
        } 

感谢 faranjit 的回答和您的 cmets。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2019-02-25
    • 2017-09-18
    • 2013-08-05
    • 1970-01-01
    • 2017-10-08
    • 1970-01-01
    • 2021-03-11
    • 2019-01-26
    相关资源
    最近更新 更多