问题
So, i have this code to make a POST request with volley:
public class MainActivity extends AppCompatActivity {
Button btnSearch;
ProgressDialog loadingDialog;
ListView lvResult;
String session_id;
RequestQueue queue;
MyCookieManager myCookieManager;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
btnSearch = (Button) findViewById(R.id.btnSearch);
lvResult = (ListView) findViewById(R.id.lvResult);
loadingDialog = new ProgressDialog(MainActivity.this);
loadingDialog.setMessage("Wait.\nLoading...");
loadingDialog.setCancelable(false);
myCookieManager = new MyCookieManager();
requestCookie(); //FIRST CALL TO GET SESSION ID
btnSearch.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
showLoading();
requestWithSomeHttpHeaders(); //CALL TO MAKE THE REQUEST WITH VALID SESSION ID
}
});
}
public void requestCookie() {
queue = Volley.newRequestQueue(this);
String url = "http://myurl.com/json/";
StringRequest postRequest = new StringRequest(Request.Method.POST, url,
new Response.Listener < String > () {
@Override
public void onResponse(String response) {
//
String x = myCookieManager.getCookieValue();
}
},
new Response.ErrorListener() {
@Override
public void onErrorResponse(VolleyError error) {
Log.d("ERROR", "Error => " + error.toString());
hideLoading();
}
}
) {
@Override
public byte[] getBody() throws AuthFailureError {
String httpPostBody = "param1=XPTO¶m2=XPTO";
return httpPostBody.getBytes();
}
@Override
public Map < String, String > getHeaders() throws AuthFailureError {
Map <String, String> params = new HashMap < String, String > ();
params.put("User-Agent", "Mozilla/5.0");
params.put("Accept", "application/json, text/javascript, */*; q=0.01");
params.put("Content-Type", "application/x-www-form-urlencoded; charset=UTF-8");
//params.put("Set-Cookie", session_id);// + " _ga=GA1.3.1300076726.1496455105; _gid=GA1.3.1624400465.1496455105; _gat=1; _gali=AguardeButton");
//"PHPSESSID=ra0nbm0l22gsnl6s4jo0qkqci1");
return params;
}
protected Response <String> parseNetworkResponse(NetworkResponse response) {
try {
String jsonString = new String(response.data, HttpHeaderParser.parseCharset(response.headers));
String header_response = String.valueOf(response.headers.values());
int index1 = header_response.indexOf("PHPSESSID=");
int index2 = header_response.indexOf("; path");
//Log.e(Utils.tag, "error is : " + index1 + "::" + index2);
session_id = header_response.substring(index1, index2);
return Response.success(jsonString, HttpHeaderParser.parseCacheHeaders(response));
} catch (UnsupportedEncodingException e) {
return Response.error(new ParseError(e));
}
}
};
queue.add(postRequest);
}
public void requestWithSomeHttpHeaders() {
queue = Volley.newRequestQueue(this);
String url = "http://myurl.com/json/";
StringRequest postRequest = new StringRequest(Request.Method.POST, url,
new Response.Listener <String> () {
@Override
public void onResponse(String response) {
Log.d("Response", response);
String x = myCookieManager.getCookieValue();
String status = "";
try {
JSONObject resultObject = new JSONObject(response);
Log.d("JSON RESULT =>", resultObject.toString());
} catch (JSONException e) {
Toast.makeText(MainActivity.this, "Request Error", Toast.LENGTH_SHORT).show();
e.printStackTrace();
}
hideLoading();
}
},
new Response.ErrorListener() {
@Override
public void onErrorResponse(VolleyError error) {
Log.d("ERROR", "Error => " + error.toString());
hideLoading();
}
}
) {
@Override
public byte[] getBody() throws AuthFailureError {
String httpPostBody = "param1=XPTO¶m2=XPTO";
return httpPostBody.getBytes();
}
@Override
public Map <String, String> getHeaders() throws AuthFailureError {
Map <String, String> params = new HashMap <String, String> ();
params.put("User-Agent", "Mozilla/5.0");
params.put("Accept", "application/json, text/javascript, */*; q=0.01");
params.put("Content-Type", "application/x-www-form-urlencoded; charset=UTF-8");
params.put("Cookie", /*myCookieManager.getCookieValue()*/ session_id + "; _ga=GA1.3.1300076726.1496455105; _gid=GA1.3.1624400465.1496455105; _gat=1; _gali=AguardeButton");
return params;
}
};
queue.add(postRequest);
}
private void showLoading() {
runOnUiThread(new Runnable() {
@Override
public void run() {
if (!loadingDialog.isShowing())
loadingDialog.show();
}
});
}
private void hideLoading() {
runOnUiThread(new Runnable() {
@Override
public void run() {
if (loadingDialog.isShowing())
loadingDialog.dismiss();
}
});
}
}
If I send a valid cookie ID this return a valid JSON object else a empty object.
I tried (unsuccessfully) to set default cookie handles like
CookieManager manager = new CookieManager();
CookieHandler.setDefault(manager);
but I get a empty object.
How to put a valid cookie session ID to post request?
回答1:
So the problem was getting a valid cookie. My mistake was to get it from the POST request itself. I kept the same working principle, getting the cookie when I started the application but using GET instead of POST and calling the root of the URL instead of the address where I get the JSON.
My solution looked like this:
public void requestCookie() {
queue = Volley.newRequestQueue(this);
String url = "http://myurl.com/";
StringRequest getRequest = new StringRequest(Request.Method.GET, url,
new Response.Listener <String> () {
@Override
public void onResponse(String response) {
String x = myCookieManager.getCookieValue();
}
},
new Response.ErrorListener() {
@Override
public void onErrorResponse(VolleyError error) {
Log.d("ERROR", "Error => " + error.toString());
hideLoading();
}
}
) {
protected Response <String> parseNetworkResponse(NetworkResponse response) {
try {
String jsonString = new String(response.data, HttpHeaderParser.parseCharset(response.headers));
String header_response = String.valueOf(response.headers.values());
int index1 = header_response.indexOf("PHPSESSID=");
int index2 = header_response.indexOf("; path");
//Log.e(Utils.tag, "error is : " + index1 + "::" + index2);
session_id = header_response.substring(index1, index2);
return Response.success(jsonString, HttpHeaderParser.parseCacheHeaders(response));
} catch (UnsupportedEncodingException e) {
return Response.error(new ParseError(e));
}
}
};
queue.add(getRequest);
}
回答2:
Using cookies with Android volley library
Request class:
public class StringRequest extends com.android.volley.toolbox.StringRequest {
private final Map<String, String> _params;
/**
* @param method
* @param url
* @param params
* A {@link HashMap} to post with the request. Null is allowed
* and indicates no parameters will be posted along with request.
* @param listener
* @param errorListener
*/
public StringRequest(int method, String url, Map<String, String> params, Listener<String> listener,
ErrorListener errorListener) {
super(method, url, listener, errorListener);
_params = params;
}
@Override
protected Map<String, String> getParams() {
return _params;
}
/* (non-Javadoc)
* @see com.android.volley.toolbox.StringRequest#parseNetworkResponse(com.android.volley.NetworkResponse)
*/
@Override
protected Response<String> parseNetworkResponse(NetworkResponse response) {
// since we don't know which of the two underlying network vehicles
// will Volley use, we have to handle and store session cookies manually
MyApp.get().checkSessionCookie(response.headers);
return super.parseNetworkResponse(response);
}
/* (non-Javadoc)
* @see com.android.volley.Request#getHeaders()
*/
@Override
public Map<String, String> getHeaders() throws AuthFailureError {
Map<String, String> headers = super.getHeaders();
if (headers == null
|| headers.equals(Collections.emptyMap())) {
headers = new HashMap<String, String>();
}
MyApp.get().addSessionCookie(headers);
return headers;
}
}
MyApp:
public class MyApp extends Application {
private static final String SET_COOKIE_KEY = "Set-Cookie";
private static final String COOKIE_KEY = "Cookie";
private static final String SESSION_COOKIE = "sessionid";
private static MyApp _instance;
private RequestQueue _requestQueue;
private SharedPreferences _preferences;
public static MyApp get() {
return _instance;
}
@Override
public void onCreate() {
super.onCreate();
_instance = this;
_preferences = PreferenceManager.getDefaultSharedPreferences(this);
_requestQueue = Volley.newRequestQueue(this);
}
public RequestQueue getRequestQueue() {
return _requestQueue;
}
/**
* Checks the response headers for session cookie and saves it
* if it finds it.
* @param headers Response Headers.
*/
public final void checkSessionCookie(Map<String, String> headers) {
if (headers.containsKey(SET_COOKIE_KEY)
&& headers.get(SET_COOKIE_KEY).startsWith(SESSION_COOKIE)) {
String cookie = headers.get(SET_COOKIE_KEY);
if (cookie.length() > 0) {
String[] splitCookie = cookie.split(";");
String[] splitSessionId = splitCookie[0].split("=");
cookie = splitSessionId[1];
Editor prefEditor = _preferences.edit();
prefEditor.putString(SESSION_COOKIE, cookie);
prefEditor.commit();
}
}
}
/**
* Adds session cookie to headers if exists.
* @param headers
*/
public final void addSessionCookie(Map<String, String> headers) {
String sessionId = _preferences.getString(SESSION_COOKIE, "");
if (sessionId.length() > 0) {
StringBuilder builder = new StringBuilder();
builder.append(SESSION_COOKIE);
builder.append("=");
builder.append(sessionId);
if (headers.containsKey(COOKIE_KEY)) {
builder.append("; ");
builder.append(headers.get(COOKIE_KEY));
}
headers.put(COOKIE_KEY, builder.toString());
}
}
}
回答3:
You getting cookie (Session id) in Login response, Save cookie in sharedpreference or other db, and use that to send in request.
for getting cookie from login request
CustomStringRequest stringRequest = new CustomStringRequest(Request.Method.POST, SIGN_IN_URL,
new Response.Listener<CustomStringRequest.ResponseM>() {
@Override
public void onResponse(CustomStringRequest.ResponseM result) {
CookieManager cookieManage = new CookieManager();
CookieHandler.setDefault(cookieManage);
progressDialog.hide();
try {
//From here you will get headers
String sessionId = result.headers.get("Set-Cookie");
String responseString = result.response;
Log.e("session", sessionId);
Log.e("responseString", responseString);
JSONObject object = new JSONObject(responseString);
CustomStringRequest class
public class CustomStringRequest extends Request<CustomStringRequest.ResponseM> {
private Response.Listener<CustomStringRequest.ResponseM> mListener;
public CustomStringRequest(int method, String url, Response.Listener<CustomStringRequest.ResponseM> responseListener, Response.ErrorListener listener) {
super(method, url, listener);
this.mListener = responseListener;
}
@Override
protected void deliverResponse(ResponseM response) {
this.mListener.onResponse(response);
}
@Override
protected Response<ResponseM> parseNetworkResponse(NetworkResponse response) {
String parsed;
try {
parsed = new String(response.data, HttpHeaderParser.parseCharset(response.headers));
} catch (UnsupportedEncodingException e) {
parsed = new String(response.data);
}
ResponseM responseM = new ResponseM();
responseM.headers = response.headers;
responseM.response = parsed;
return Response.success(responseM, HttpHeaderParser.parseCacheHeaders(response));
}
public static class ResponseM {
public Map<String, String> headers;
public String response;
}
}
set cookie when add request to server..
@Override
public Map<String, String> getHeaders() throws AuthFailureError {
Map<String, String> headers = new HashMap<String, String>();
String session=sharedPreferences.getString("sessionId","");
headers.put("Cookie",session);
return headers;
}
来源:https://stackoverflow.com/questions/44273674/how-to-put-cookie-session-id-into-volley-request