2015-11-10 25 views
0

我正在開發一個Android應用程序,我需要從遠程服務器的MySQL數據庫中獲取結果。我寫了一些PHP腳本來查詢數據庫並以JSON格式輸出結果。Android - Volley對遠程服務器的JSON請求只能正常工作

問題是請求僅在第一次獲取預期結果。當我用不同的POST參數發送相同的請求時,它會再次返回第一個結果。我修改了PHP腳本以在JSON結果中附加POST參數,並嘗試記錄POST參數。這也是第一個參數。 如果我從設備上卸載應用程序並重新安裝,它將再次僅在第一次返回正確的JSON。

注意:當我運行相同的代碼與本地主機(WAMPP)上相同的PHP腳本和相同的數據庫,一切工作完美。 我嘗試使用谷歌瀏覽器擴展Postman來檢查遠程服務器的輸出,它按預期工作。所以,我可以確認問題出在我的應用程序/代碼上。

這裏是我的CustomJSONObjectRequest類:

public class CustomJSONObjectRequest extends Request<JSONObject> { 

private Listener<JSONObject> listener; 
private Map<String, String> params; 

public CustomJSONObjectRequest(String url, Map<String, String> params, 
        Listener<JSONObject> reponseListener, ErrorListener errorListener) { 
    super(Method.GET, url, errorListener); 
    this.listener = reponseListener; 
    this.params = params; 
} 

public CustomJSONObjectRequest(int method, String url, Map<String, String> params, 
        Listener<JSONObject> reponseListener, ErrorListener errorListener) { 
    super(method, url, errorListener); 
    this.listener = reponseListener; 
    this.params = params; 
} 

protected Map<String, String> getParams() 
     throws com.android.volley.AuthFailureError { 
    return params; 
}; 

@Override 
protected Response<JSONObject> parseNetworkResponse(NetworkResponse response) { 
    try { 
     String jsonString = new String(response.data, 
       HttpHeaderParser.parseCharset(response.headers)); 
     return Response.success(new JSONObject(jsonString), 
       HttpHeaderParser.parseCacheHeaders(response)); 
    } catch (UnsupportedEncodingException e) { 
     return Response.error(new ParseError(e)); 
    } catch (JSONException je) { 
     return Response.error(new ParseError(je)); 
    } 
} 

@Override 
protected void deliverResponse(JSONObject response) { 
    listener.onResponse(response); 
} 
} 

這是怎麼了發送請求:

  String item_name = getIntent().getExtras().getString("item_name"); 
      String url = getString(R.string.remote_server)+"fetch-item-list.php"; 

      CustomJSONObjectRequest jsObjRequest = new CustomJSONObjectRequest(Request.Method.POST, url, null, new Response.Listener<JSONObject>() { 
       @Override 
       public void onResponse(JSONObject response) { 


        try { 
         Log.d("item name from intent extra", item_name); //intent extra 
         Log.d("response", response.toString()); //json response 
         Log.d("item name from response", response.getString("item_name")); //post parameter. This and the intent extra should be same 

        } catch (JSONException e) { 
         e.printStackTrace(); 
        } 
       } 
      }, new Response.ErrorListener() { 
       @Override 
       public void onErrorResponse(VolleyError error) { 
        Toast.makeText(getApplicationContext(), error.toString(), Toast.LENGTH_SHORT).show(); 
       } 
      }) { 
       @Override 
       protected Map<String, String> getParams() throws AuthFailureError { 
        Map<String, String> params = new HashMap<>(); 

        params.put("item_name", item_name); 

        return params; 
       } 

       @Override 
       public Map<String, String> getHeaders() throws AuthFailureError { 
        Map<String, String> header = new HashMap<String, String>(); 
        header.put("Content-Type", "application/json; charset=utf-8"); 
        return header; 
       } 
      }; 



      MyVolleySingleton.getInstance(getApplicationContext()).addToRequestQueue(jsObjRequest); 

這是logcat的:

D/item name from intent extra: apple 
D/Response: {"data":[{"item_discount":"0.00","item_price":"50.00","unique_id":"181................ 
D/item name from response: orange 
+0

我沒有找到錯誤,但新的CustomJSONObjectRequest(Request.Method.POST,這裏你使用POST和這裏使用超級(Method.GET,url,errorListener); GET爲什麼是這樣? – Amsheer

+0

檢查你的服務器應用程序,橙'是默認的項目名稱reponsed,如果它沒有得到任何item_name – BNK

+0

@Amsheer我打電話給第二個構造函數,該方法作爲參數,並調用超級傳遞它 – amzer

回答

0

我想我找到解決方案

看起來像JSON響應得到緩存,所以第一個請求的響應被緩存,並且下一個請求從未發送到服務器。緩存的JSON響應已針對其他任何請求返回。

我只需要禁用緩存。 在添加到請求隊列之前,我添加了行jsObjRequest.setShouldCache(false);

jsObjRequest.setShouldCache(false); 
MyVolleySingleton.getInstance(getApplicationContext()).addToRequestQueue(jsObjRequest); 

感謝此question

但我仍然不明白爲什麼它沒有這個設置在localhost上工作。

+1

這是因爲服務器響應支持輸出緩存,你可以在這裏閱讀更多信息https://developers.google.com/web/fundamentals/performance/optimizing-content-efficiency/http-caching?hl= en#cache-control – BNK

+0

是啊!感謝您的鏈接。 – amzer