Android volley is not sending params - android

The code which does not work is below. See anything wrong with this code , why it is not sending parameters. I am new to Android.
private void sendParams()
{
JsonArrayRequest movieReq = new JsonArrayRequest(AppConfig.URL_Q_RECIPIES,
new Response.Listener<JSONArray>() {
#Override
public void onResponse(JSONArray response) {
Log.d(TAG, response.toString());
hidePDialog();
// Parsing json
for (int i = 0; i < response.length(); i++) {
try {
JSONObject obj = response.getJSONObject(i);
Recipie movie = new Recipie();
movie.setRecipieName(obj.getString("recipie_name"));
movie.setId(obj.getInt("id"));
// build the image URL here
String s = AppConfig.URL_IMAGE + obj.getInt("id") + ".jpeg";
movie.setImageURL(s);
movie.setPrimaryIngrediant(obj.getString("prim_ingr"));
movie.setUrl(obj.getString("url"));
// adding movie to movies array movie is nothing but recipie
movieList.add(movie);
} catch (JSONException e) {
e.printStackTrace();
}
}
// notifying list adapter about data changes
// so that it renders the list view with updated data
adapter.notifyDataSetChanged();
}
}, new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
Log.e(TAG, "Filter error: " + error.getMessage());
Toast.makeText(getApplicationContext(),
error.getMessage(), Toast.LENGTH_LONG).show();
hidePDialog();
}
}) {
#Override
protected Map<String, String> getParams () {
// Posting parameters to login url
Map<String, String> params = new HashMap<String, String>();
params.put("ind_ajwain", Integer.toString(session.isAjwainChecked()));
//params.put("ind_asaftide", Integer.toString(session.isAsaftideChecked()));
params.put("rec_name", "chicken"); /// change this
params.put("ind_ginger", "0");
//params.put("password", password);
return params;
}
};
Log.d(TAG, movieReq.toString());
//movieReq.
AppController.getInstance().addToRequestQueue(movieReq);
}
I followed this link to get coding don : Source: https://www.androidhive.info/2012/01/android-login-and-registration-with-php-mysql-and-sqlite/
I have not made much changes above, only changing parameters.

For sending data to server using Volley refer below code.
Step1 : Use POST method to send data.
Create below method :
private void makeJsonSend() {
StringRequest jsonObjReq = new StringRequest(Request.Method.POST,Const.ServiceType.URL,
new Response.Listener<String>() {
#Override
public void onResponse(String response) {
Log.e("response:forgot", response);
jsonParseResponse(response);
}
}, new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
//show error message here
}
}) {
#Override
protected Map<String, String> getParams() throws AuthFailureError {
Map<String, String> params = new HashMap<String, String>();
params.put("email","email");
//pass parameter here
Log.i("request send data", params.toString());
return params;
}
#Override
public Map<String, String> getHeaders() throws AuthFailureError {
HashMap<String, String> headers = new HashMap<>();
//If you have header parameter then set here
return headers;
}
};
AppController.getInstance().addToRequestQueue(movieReq);
}
Step 2: Response method where you have get response of that operation.
private void jsonParseResponse(String response) {
try {
JSONObject jsonObject = new JSONObject(response);
if (jsonObject.getString("status").equals("200")) {
cc.showToast(jsonObject.getString("message"));
} else {
cc.showToast(jsonObject.getString("message"));
}
} catch (JSONException e) {
e.printStackTrace();
Log.e("Forgot Error",e.toString());
}
}

You didn't pass any request method in new JsonArrayRequest. You have to pass Request.Method.POST or Request.Method.GET

Related

How to solve Error in json parsing using volley POST?

Hi I am using volley as JSON Parsing. I am using POST method and sending parameters in post request. I am getting following error when parsing the data, I am getting following error. I want to use volley. I have tried with JsonArrayRequest but it does not allow to send parameters as JSONObject,which I am using in my code.
org.json.JSONArray cannot be converted to JSONObject
Request is like
{
"city":"acd",
"user_id":"82",
"phone_number1":"1232131231",
"my_type":"asf"
}
Response is like
[{
"name":"dfdfd",
}]
Following is my code
private void Search_Refer() {
//initialize the progress dialog and show it
progressDialog = new ProgressDialog(SearchReferNameActivity.this);
progressDialog.setMessage("Please wait....");
progressDialog.show();
try {
JSONObject jsonBody = new JSONObject();
jsonBody.put("city", "acb");
jsonBody.put("user_id", "82");
jsonBody.put("phone_number1", "12332123231");
jsonBody.put("my_type", "asf");
JsonObjectRequest jsonOblect = new JsonObjectRequest(Request.Method.POST, Constants.BASE_URL1+"api/lab/search", jsonBody, new Response.Listener<JSONObject>() {
#Override
public void onResponse(JSONObject response) {
Toast.makeText(getApplicationContext(), response.toString(), Toast.LENGTH_LONG).show();
Log.e("Search EROOR", response.toString());
try {
JSONArray itemArray=new JSONArray(response);
dataModelArrayList = new ArrayList<>();
for (int i = 0; i < itemArray.length(); i++) {
SearchModel playerModel = new SearchModel();
JSONObject dataobj = itemArray.getJSONObject(i);
//playerModel.setProduct_name(dataobj.getString("name"));
playerModel.setRadiology_store_first_name(dataobj.getString("radiology_store_first_name"));
dataModelArrayList.add(playerModel);
}
} catch (JSONException e) {
e.printStackTrace();
}
progressDialog.dismiss();
/* Intent intent = new Intent(SearchReferNameActivity.this, SearchResult.class);
intent.putExtra("Search_result", dataModelArrayList);
startActivity(intent);*/
}
}, new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
Toast.makeText(getApplicationContext(), "Response: " + error.toString(), Toast.LENGTH_SHORT).show();
System.out.println("Search Eroor"+error.toString());
progressDialog.dismiss();
}
}){
#Override
public String getBodyContentType() {
return "application/json";
}
#Override
public Map<String, String> getHeaders() throws AuthFailureError {
HashMap<String, String> headers = new HashMap<String, String>();
headers.put("Authorization", "Bearer "+deviceToken);
return headers;
}
};
jsonOblect.setRetryPolicy(new DefaultRetryPolicy(
10000,
DefaultRetryPolicy.DEFAULT_MAX_RETRIES,
DefaultRetryPolicy.DEFAULT_BACKOFF_MULT));
MyApplication.getInstance().addToRequestQueue(jsonOblect,"postrequest");
} catch (JSONException e) {
e.printStackTrace();
}
// Toast.makeText(getApplicationContext(), "done", Toast.LENGTH_LONG).show();
}
Use JsonArrayRequest or StringRequest in place of JsonObjectRequest
JsonArrayRequest
change the following response parameter to JSONArray
Instead of new Response.Listener<JSONObject> Use new Response.Listener<JSONArray>
// JSONArray insated of JSONObject
public void onResponse(JSONArray response) {
}
Use Below code
StringRequest stringRequest = new StringRequest(Request.Method.POST, "api/lab/search", new Response.Listener<String>() {
#Override
public void onResponse(String response) {
}
}, new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
}
}) {
#Override
protected Map<String, String> getParams() throws AuthFailureError {
Map<String, String> params = new HashMap<>();
params.put("city", "abcd");
params.put("user_id", "82");
params.put("phone_number1", "01235467895");
params.put("my_type", "asf");
return params;
}
};

onResponse method of Android Volley is not executed

I am using Volley for networking and connect to my REST API. The following code shows the onCreate method of my MainActivity. Here I want to make a GET request to my url and receive the JSON information. But it's not working. I made different debug points all over the code. The last thing which is executed is the initialization of the arrReq. onResponse and onErrorResponse are not executed and I don't know what is the matter.
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
setupToolBar();
setupPagerAdapter();
setupFloatingButton();
getDeviceId();
JsonArrayRequest arrReq = new JsonArrayRequest(com.android.volley.Request.Method.GET, "http://localhost:8888/api/entities", null,
new Response.Listener<JSONArray>() {
#Override
public void onResponse(JSONArray response) {
// Check the length of our response (to see if there are any entities)
if (response.length() > 0) {
// There are entities so let's loop through them all.
for (int i = 0; i < response.length(); i++) {
try {
// Get each entity
JSONObject jsonObj = response.getJSONObject(i);
String locData = jsonObj.get("entity").toString();
} catch (JSONException e) {
// If there is an error then output this to the logs.
Log.e("Volley", "Invalid JSON Object.");
}
}
} else {
// There aren't any entities. So do nothing!
}
}
},
new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
// If there a HTTP error then add a note to our list.
Log.e("Volley", error.toString());
}
}
);
}
When I execute the url in my browser on my device the JSON code is received:
{
"status":"success",
"data":[
{
"entity":"(17,)"
},
{
"entity":"(21,)"
},
{
"entity":"(201,)"
}
],
"message":"Retrieved entities"
}
The log does not show any error.
JsonArrayRequest request = new JsonArrayRequest (Request.Method.GET, URL, new Response.Listener<String>() {
#Override
public void onResponse(JSONArray response) {
if (!response.equals(null)) {
Log.e("Your Array Response", response);
} else {
Log.e("Your Array Response", "Data Null");
}
}
}, new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
Log.e("error is ", "" + error);
}
}) {
//This is for Headers If You Needed
#Override
public Map<String, String> getHeaders() throws AuthFailureError {
//Map<String, String> params = new HashMap<String, String>();
// params.put("Content-Type", "application/json; charset=UTF-8");
// params.put("Authorization", "bearer " + token);
return params;
}
//Pass Your Parameters here
#Override
protected Map<String, String> getParams() {
Map<String, String> params = new HashMap<String, String>();
/*params.put("User", UserName);
params.put("Pass", PassWord);*/
return params;
}
};
RequestQueue queue = Volley.newRequestQueue(getApplicationContext());
queue.add(request);
Try this one
It might be a permission issue,
did you add your manifest.xml file the following code:
<uses-permission android:name="android.permission.INTERNET" />
Finally I got it. The problem was that I get a JSONObject as response but instanciated a JSONArrayRequest. When I change that into a JSONObjectRequest it works perfectly.

Android Volley calling oData using Request.POST giving 403 Error

I am calling SAP's oData Service using Volley API from Android and getting HTTP 403 Error for the Request.POST. But for the Request.GET for another Service program is working fine. May I know if there is any issue with my code calling oData Service.
Iam passing MYSAPSSO2 token and CSRF Token obtained from my first request call. But getting Authentication error. Any idea what is missing here?
Same oData POST service using JQUERY/SAPUI5 is working fine without any issues.
try {
/** json object parameter**/
JSONObject jsonObject = new JSONObject();
jsonObject.put("SO", so);
jsonObject.put("STATUS", status);
jsonObject.put("NET_VALUE", amount);
Log.i("XXXX", thisMethod+"jsonObject params"+ jsonObject.toString() + "");
JsonObjectRequest jsonObjectRequest = new JsonObjectRequest(Request.Method.GET, url, null, new Response.Listener<JSONObject>() {
#Override
public void onResponse(JSONObject jsonRespObj) {
Log.i("XXXX", thisMethod+"Response from notification service: " + jsonRespObj.toString());
}
}, new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError volleyError) {
Log.i("XXXXX", thisMethod+"Error Response: " + volleyError);
volleyError.printStackTrace();
}
}
) {
#Override
public Map<String, String> getHeaders() throws AuthFailureError {
Map<String, String> params = new HashMap<String, String>();
if (mysapsso2 != null) {
Log.i("XXX", thisMethod+"MYSAPSSO2 is : " + TokenHandler.getMYSAPSSO2Token());
Log.i("XXXX", thisMethod+"X-CSRF-Token is : " + TokenHandler.getCSRFToken());
params.put("Cookie", ServiceClass.mysapsso2);
params.put("X-CSRF-Token", TokenHandler.getCSRFToken());
params.put("contentType", "application/json");
}
return params;
}
};
queue.add(jsonObjectRequest);
} catch (JSONException e) {
Log.e("XXX", thisMethod+"There was an error => " + e.getMessage());
e.printStackTrace();
}
catch (Exception e) {
Log.e("XXXX", thisMethod+"There was an error => " + e.getMessage());
e.printStackTrace();
}
Use StringRequest insted of JsonObjectRequest. Get json encoded response to a string & create json object. Below code work fine for me. try it.
public void getPostJsonData() {
final String URL = "URL";
StringRequest stringRequest = new StringRequest(Request.Method.POST, URL,
new Response.Listener<String>() {
#Override
public void onResponse(String response) {
try {
JSONObject obj = new JSONObject(response);
JSONArray jsonArray = obj.getJSONArray("server_response");
for (int i = 0; i < jsonArray.length(); i++) {
JSONObject JO = jsonArray.getJSONObject(i);
fname = JO.getString("firstname"); //or JO.toString()
lname = JO.getString("lastname");
}
} catch (JSONException e) {
e.printStackTrace();
}
}
},
new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
Toast.makeText(ActivityName.this, error.toString(), Toast.LENGTH_LONG).show();
}
}) {
#Override
protected Map<String, String> getParams() throws AuthFailureError {
HashMap<String, String> hashMap = new HashMap<String, String>();
hashMap.put("Cookie", ServiceClass.mysapsso2.toString);
hashMap.put("X-CSRF-Token", TokenHandler.getCSRFToken().toString);
hashMap.put("contentType", "application/json");
return hashMap;
}
};
final RequestQueue requestQueue = Volley.newRequestQueue(this);
requestQueue.add(stringRequest);
requestQueue.addRequestFinishedListener(new RequestQueue.RequestFinishedListener<Object>() {
#Override
public void onRequestFinished(Request<Object> request) {
requestQueue.getCache().clear();
}
});
}

Volley GET with parameters

I have a web service which gives data in JSON array format. Right now the data is being fetched just by passing the URL. But now I want to pass a parameter to get the JSON response. This web service has GET & POST methods.
I tried with Volley - Sending a POST request using JSONArrayRequest answer, but I couldn't implement it in my code. It would be really helpful if somebody could explain, how to achieve this in my code.
This is how my code looks like
String HTTP_SERVER_URL = "https://192.168.1.7/STUDENTWS/Default.asmx/StudentDataJson?InFacultyID=string";
public void JSON_WEB_CALL(){
//mSwipeRefreshLayout.setRefreshing(true);
jsonArrayRequest = new JsonArrayRequest(HTTP_SERVER_URL,
new Response.Listener<JSONArray>() {
#Override
public void onResponse(JSONArray response) {
JSON_PARSE_DATA_AFTER_WEBCALL(response);
}
},
new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
}
});
requestQueue = Volley.newRequestQueue(this);
requestQueue.add(jsonArrayRequest);
}
public void JSON_PARSE_DATA_AFTER_WEBCALL(JSONArray array){
for(int i = 0; i<array.length(); i++) {
DataModel GetDataModel = new DataModel();
JSONObject json = null;
try {
json = array.getJSONObject(i);
GetDataModel.setId(json.getString("STUDENTID"));
GetDataModel.setPlateNo(json.getString("GRADE"));
GetDataModel.setPlateCode(json.getString("HOUSE"));
}
catch (JSONException e)
{
e.printStackTrace();
}
DataAdapterClassList.add(GetDataModel);
mSwipeRefreshLayout.setRefreshing(false);
}
recyclerViewadapter = new NewRecyclerViewAdapter(DataAdapterClassList, this);
recyclerView.setAdapter(recyclerViewadapter);
if (array.length()!=0) {
SHOW_ALERT(array);
sendNotification(recyclerView, array);
}
}
For get with params you should create StringRequest. For example:
RequestQueue queue = Volley.newRequestQueue(context);
StringRequest sr = new StringRequest(Request.Method.GET, "http://headers.jsontest.com/",
new Response.Listener<String>() {
#Override
public void onResponse(String response) {
Log.e("HttpClient", "success! response: " + response.toString());
}
},
new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
Log.e("HttpClient", "error: " + error.toString());
}
})
{
#Override
protected Map<String,String> getParams(){
Map<String,String> params = new HashMap<String, String>();
params.put("user","YOUR USERNAME");
params.put("pass","YOUR PASSWORD");
return params;
}
#Override
public Map<String, String> getHeaders() throws AuthFailureError {
Map<String,String> params = new HashMap<String, String>();
params.put("Content-Type","application/x-www-form-urlencoded");
return params;
}
};
// for json object
Map<String, String> jsonParams = new HashMap<String, String>();
jsonParams.put("fullname",fullName);
jsonParams.put("email",email);
jsonParams.put("password",password);
// for json array make any list.List will be converted to jsonArray
// example-----
// ArrayList<String> jsonParams =new ArrayList();
// jsonParams.add("Test1")
// jsonParams.add("Test2")
JsonObjectRequest objectRequest=new JsonObjectRequest(Request.Method.POST, url, new JSONObject(jsonParams), new Response.Listener<JSONObject>() {
#Override
public void onResponse(JSONObject response) {
}
}, new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
Log.e(TAG, "onErrorResponse: ",error );
Toast.makeText(ActivitySignUp.this,error.getMessage(), Toast.LENGTH_LONG).show();
}
}){
#Override
public Map<String, String> getHeaders() throws AuthFailureError {
HashMap<String,String> header=new HashMap<String, String>();
header.put("Content-Type","application/json");
return header;
}
};
If you want to pass a param to your server, then you might wanna do a POST method, else.. if you only wanted to get the data, then GET method is the best way... there's also header that you can use to pass data, but, I wouldn't recommend to use header for sending params... that's a sore eyes
Edit
//Set you method POST or GET
JsonObjectRequest(Request.Method.GET(/*here can set to POST too*/), url, null,
new Response.Listener<JSONObject>()
{
#Override
public void onResponse(JSONObject response) {
// display response
Log.d("Response", response.toString());
}
},
new Response.ErrorListener()
{
#Override
public void onErrorResponse(VolleyError error) {
Log.d("Error.Response", response);
}
}
);

Android Volley - JsonArrayRequest with post parameters

I'm using Volley to interact with an API. I need to send a post request with parameters to a service that returns a JSONArray.
I'm overriding the method protected Map<String, String> getParams() but it is not working:
JsonArrayRequest eventoReq = new JsonArrayRequest(Configuracion.URL_API_PROXIMOS_EVENTOS,
new Response.Listener<JSONArray>() {
#Override
public void onResponse(JSONArray response) {
Log.d(TAG, response.toString());
hidePDialog();
// Parsea json
for (int i = 0; i < response.length(); i++) {
try {
JSONObject obj = response.getJSONObject(i);
Evento evento = new Evento();
evento.setCod_evento(obj.getInt("cod_evento"));
evento.setTitulo(obj.getString("titulo"));
evento.setDescripcion(obj.getString("descripcion"));
evento.setDireccion(obj.getString("direccion"));
evento.setImagen(obj.getString("imagen"));
evento.setPuntuacion((float) obj.getDouble("puntuacion"));
// Añade el evento al listado
listaEventos.add(evento);
} catch (JSONException e) {
e.printStackTrace();
}
}
// Actualiza el adaptador
adapter.notifyDataSetChanged();
}
}, new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
VolleyLog.d(TAG, "Error: " + error.getMessage());
hidePDialog();
}
}){
#Override
protected Map<String, String> getParams() {
// Posting parameters to login url
Map<String, String> params = new HashMap<String, String>();
params.put("tag", "eventos_proximos_usuario");
params.put("cod_usuario", cod_usuario);
return params;
}
#Override
public int getMethod() {
return Method.POST;
}
};
// Añade la peticion a la cola
AppController.getInstance().addToRequestQueue(eventoReq);
Try ...
StringRequest instead..
Reference:
https://android.googlesource.com/platform/frameworks/volley/+/master/src/main/java/com/android/volley/toolbox
JsonObjectRequest extends JsonRequest
whereas StringRequest extends Request
StringRequest eventoReq = new StringRequest(Request.Method.POST,Configuracion.URL_API_PROXIMOS_EVENTOS,
new Response.Listener<String>() {
#Override
public void onResponse(String response) {
Log.d(TAG, response.toString());
hidePDialog();
try{
JSONArray j= new JSONArray(response);
// Parsea json
for (int i = 0; i < j.length(); i++) {
try {
JSONObject obj = j.getJSONObject(i);
Evento evento = new Evento();
evento.setCod_evento(obj.getInt("cod_evento"));
evento.setTitulo(obj.getString("titulo"));
evento.setDescripcion(obj.getString("descripcion"));
evento.setDireccion(obj.getString("direccion"));
evento.setImagen(obj.getString("imagen"));
evento.setPuntuacion((float) obj.getDouble("puntuacion"));
// Añade el evento al listado
listaEventos.add(evento);
} catch (JSONException e) {
e.printStackTrace();
}
}
// Actualiza el adaptador
adapter.notifyDataSetChanged();
} catch (JSONException e) {
e.printStackTrace();
}
}
}, new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
VolleyLog.d(TAG, "Error: " + error.getMessage());
hidePDialog();
}
}){
#Override
protected Map<String, String> getParams() {
// Posting parameters to login url
Map<String, String> params = new HashMap<String, String>();
params.put("tag", "eventos_proximos_usuario");
params.put("cod_usuario", cod_usuario);
return params;
}
};
// Añade la peticion a la cola
AppController.getInstance().addToRequestQueue(eventoReq);
Me just a beginner hope it helps!!!
try like this,
I think you don't need to override the getMethod() method.
Pass the method type (i.e Method.POST) name with in the JsonObjectRequest or JsonArrayRequest like below.
JsonObjectRequest jsonObjReq = new JsonObjectRequest(Method.POST,
url, null,
new Response.Listener<JSONObject>() {
#Override
public void onResponse(JSONObject response) {
Log.d(TAG, response.toString());
pDialog.hide();
}
}, new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
VolleyLog.d(TAG, "Error: " + error.getMessage());
pDialog.hide();
}
}) {
#Override
protected Map<String, String> getParams() {
// Posting parameters to login url
Map<String, String> params = new HashMap<String, String>();
params.put("tag", "eventos_proximos_usuario");
params.put("cod_usuario", cod_usuario);
return params;
}
};
// Adding request to request queue
AppController.getInstance().addToRequestQueue(jsonObjReq, tag_json_obj);
I faced the same problem when I started to use Volley in my android project. I solved the problem by using StringRequest instead of JsonArrayRequest.
for example if you want to show a ListView with some server data...
Just use a simple StringRequest instead of JSONArrayRequest and implements the onResponse Methode like this :
public void onResponse(String response){
try{
JSONArray jsonArray=new JSONArray(response);
for(int i=0;i<jsonArray.length();i++) {
try {
JSONObject jsonObject = jsonArray.getJSONObject(i);
// do something
} catch (JSONException e) {
e.printStackTrace();
}
}
}catch (JSONException e2){
e2.printStackTrace();
}
}
}
StringRequest request = new StringRequest(Request.Method.POST, YourUrl, new Response.Listener<String>() {
#Override
public void onResponse(String response) {
if (!response.equals(null)) {
Log.e("Your Array Response", response);
} else {
Log.e("Your Array Response", "Data Null");
}
}
}, new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
Log.e("error is ", "" + error);
}
}) {
//This is for Headers If You Needed
#Override
public Map<String, String> getHeaders() throws AuthFailureError {
Map<String, String> params = new HashMap<String, String>();
params.put("Content-Type", "application/json; charset=UTF-8");
params.put("token", ACCESS_TOKEN);
return params;
}
//Pass Your Parameters here
#Override
protected Map<String, String> getParams() {
Map<String, String> params = new HashMap<String, String>();
params.put("User", UserName);
params.put("Pass", PassWord);
return params;
}
};
RequestQueue queue = Volley.newRequestQueue(getApplicationContext());
queue.add(request);

Categories

Resources