0

我有一个在其他 android 设备上运行良好的 android 应用程序,但它在运行 android 版本 4.0.4 的三星 s3 上失败。Retrofit 抛出 404(找不到页面错误),但页面存在,如果我在 wifi 上发出相同的请求,它运行良好。任何对可能行为不端有想法的人。谢谢

请在堆栈跟踪下方找到

    retrofit.RetrofitError: 404 Not Found
    at retrofit.RestAdapter$RestHandler.invokeRequest (RestAdapter.java:388)
    at retrofit.RestAdapter$RestHandler.access$100 (RestAdapter.java:220)
    at retrofit.RestAdapter$RestHandler$2.obtainResponse (RestAdapter.java:278)
    at retrofit.CallbackRunnable.run (CallbackRunnable.java:42)
    at java.util.concurrent.ThreadPoolExecutor.runWorker (ThreadPoolExecutor.java:1076)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run (ThreadPoolExecutor.java:569)
    at retrofit.Platform$Android$2$1.run (Platform.java:142)
    at java.lang.Thread.run (Thread.java:856)

下面是我用来拨打电话的代码

    val tailorsInterface = RestAdapter.Builder()
                .setEndpoint(resources.getString(R.string.base_url))
                .build().create(TailorsInterface::class.java)

    tailorsInterface.addTailor(txtName.text.toString(), txtEmail.text.toString(),
                Utils.parsePhone(txtPhone.text.toString(), "254"), txtAddress.text.toString(),
                txtLon.text.toString(), txtLat.text.toString(), txtPassword.text.toString(),
                Common.LOCATIONS!!.get(spTowns.selectedItemPosition).id, object : Callback<DefaultResponse> {


            override fun success(defaultResponse: DefaultResponse, response: Response) {
                dialog.hide()
                if(defaultResponse.success == 1.toLong()){
                    val alertDialog: AlertDialog
                    val builder = AlertDialog.Builder(this@TailorsRegisterActivity)
                            .setTitle(resources.getString(R.string.app_name))
                            .setMessage("Tailor successfully registered, click OK to continue to login")
                            .setPositiveButton("OK") { dialog, which -> run{dialog.dismiss()
                                val loginIntent: Intent = Intent(this@TailorsRegisterActivity, TailorsLoginActivity::class.java)
                                startActivity(loginIntent)
                            } }
                    alertDialog = builder.create()
                    alertDialog.show()

                }else{
                    val alertDialog: AlertDialog
                    val builder = AlertDialog.Builder(this@TailorsRegisterActivity)
                            .setTitle(resources.getString(R.string.app_name))
                            .setMessage("An Error occurred please try again later")
                            .setPositiveButton("OK") { dialog, which -> run{dialog.dismiss()
                                finish()} }
                    alertDialog = builder.create()
                    alertDialog.show()
                }
            }

    @FormUrlEncoded
    @POST("/tailors")
    public fun addTailor(@Field("name") name: String, @Field("email") email: String,
                     @Field("phone") phone: String, @Field("address") address: String,
                     @Field("lon") lon: String, @Field("lat") lat: String,
                     @Field("password") password: String, @Field("town") town: Int,
                     cb: Callback<DefaultResponse>)

    data class DefaultResponse (
            var success: Long,
            var message: String
   )
4

1 回答 1

0

After many days of debugging trying to figure out what the issue I finally found a solution the issue is not retrofit but it's the webserver I am using. I have my application done in clojure and I am using http-kit as my webserver and compojure for routing.

For some reason requests that are coming from s3 the uri in the http-kit request map also includes the host hence it's not being mapped to any route on my defroute. For example say if the route I am looking for is /login the uri in the http-kit request map for the request coming from the s3 contains http://example.com/login but from the other phones it contains /login. Hence the uri doesn't match any of my routes I have defined in the compojure defroute and goes straight to not-found and hence the 404 error

The Solution

To solve this problem I had to extend Compojure routes.clj and added the following function

(defn other-found
"if for some reason the route is defined and is not found "
[body]
(fn [request]
  (-> (response/render body request)
    (status 200)
    (cond-> (= (:request-method request) :head) (assoc :body nil)))))

In defroute if the uri is not matched I use the function other-found and pass it the the function not-found-page(you can name this function whatever you want to call it) in the function I get the uri from the request parameter parse it and get the endpoint then use condp to map the end point to the appropriate function.

Hope this helps someone with a similar problem.

于 2016-05-07T18:00:18.263 回答