Send JSON body with JsonObjectRequest And GET request - java

I need to send a json code, via the get method.
I tried to send through a JsonObjectRequest with the method, url and the parameters, the response was null and the json was not sent.
JSONObject request = new JSONObject();
try {
request.put("CodigoInicial", "1");
request.put("CodigoFinal", "2");
;
} catch (JSONException e) {
e.printStackTrace();
}
// Make request for JSONObject
JsonObjectRequest jsonObjReq = new JsonObjectRequest(
Request.Method.GET, url2,request,
new Response.Listener<JSONObject>() {
#Override
public void onResponse(JSONObject response) {
// Log.d(TAG, response.toString() + " i am queen");
try {
JSONArray jsonArray = response.getJSONArray("LinhasClientes");
for (int i = 0; i < jsonArray.length(); i++) {
JSONObject employee = jsonArray.getJSONObject(i);
int codigo = employee.getInt("Codigo");
String Nome = employee.getString("Nome");
String NumContrib = employee.getString("NumContrib");
//textView.append(Nome + ", " + String.valueOf(codigo) + ", " + NumContrib + "\n\n");
}
} catch (JSONException e) {
e.printStackTrace();
}
Toast.makeText(getApplicationContext(),
response.toString()+"i am queen", Toast.LENGTH_SHORT).show();
}
}, new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
//VolleyLog.d(TAG, "Error: " + error.getMessage());
Toast.makeText(getApplicationContext(),
error.getMessage(), Toast.LENGTH_SHORT).show();
}
}) {
/**
* Passing some request headers
*/
#Override
public Map<String, String> getHeaders() throws AuthFailureError {
HashMap<String, String> headers = new HashMap<String, String>();
headers.put("Content-Type", "application/json; charset=utf-8");
headers.put("CodigoInicial","1");
headers.put("C`enter code here`odigoFinal","2");
return headers;
}
};
// Adding request to request queue
Volley.newRequestQueue(this).add(jsonObjReq);

The problem is the implementation of the createHttpRequest method in com.android.volley.toolbox.HttpClientStack.java which will add the body only if the request method is POST, PUT or PATCH.
/**
* Creates the appropriate subclass of HttpUriRequest for passed in request.
*/
#SuppressWarnings("deprecation")
/* protected */ static HttpUriRequest createHttpRequest(Request<?> request,
Map<String, String> additionalHeaders) throws AuthFailureError {
switch (request.getMethod()) {
case Method.DEPRECATED_GET_OR_POST: {
// This is the deprecated way that needs to be handled for backwards compatibility.
// If the request's post body is null, then the assumption is that the request is
// GET. Otherwise, it is assumed that the request is a POST.
byte[] postBody = request.getPostBody();
if (postBody != null) {
HttpPost postRequest = new HttpPost(request.getUrl());
postRequest.addHeader(HEADER_CONTENT_TYPE, request.getPostBodyContentType());
HttpEntity entity;
entity = new ByteArrayEntity(postBody);
postRequest.setEntity(entity);
return postRequest;
} else {
return new HttpGet(request.getUrl());
}
}
case Method.GET:
return new HttpGet(request.getUrl());
case Method.DELETE:
return new HttpDelete(request.getUrl());
case Method.POST: {
HttpPost postRequest = new HttpPost(request.getUrl());
postRequest.addHeader(HEADER_CONTENT_TYPE, request.getBodyContentType());
setEntityIfNonEmptyBody(postRequest, request);
return postRequest;
}
case Method.PUT: {
HttpPut putRequest = new HttpPut(request.getUrl());
putRequest.addHeader(HEADER_CONTENT_TYPE, request.getBodyContentType());
setEntityIfNonEmptyBody(putRequest, request);
return putRequest;
}
case Method.HEAD:
return new HttpHead(request.getUrl());
case Method.OPTIONS:
return new HttpOptions(request.getUrl());
case Method.TRACE:
return new HttpTrace(request.getUrl());
case Method.PATCH: {
HttpPatch patchRequest = new HttpPatch(request.getUrl());
patchRequest.addHeader(HEADER_CONTENT_TYPE, request.getBodyContentType());
setEntityIfNonEmptyBody(patchRequest, request);
return patchRequest;
}
default:
throw new IllegalStateException("Unknown request method.");
}
}
So you have to use your own implementation of HttpStack.java or you override HttpClientStack class.
First of all your should replace your initialization of RequestQueue from
RequestQueue requestQueue = Volley.newRequestQueue(sContext);
to
String userAgent = "volley/0";
try {
String packageName = getContext().getPackageName();
PackageInfo info = getContext().getPackageManager().getPackageInfo(packageName, 0);
userAgent = packageName + "/" + info.versionCode;
} catch (PackageManager.NameNotFoundException e) {}
HttpStack httpStack = new OwnHttpClientStack(AndroidHttpClient.newInstance(userAgent));
RequestQueue requesQueue = Volley.newRequestQueue(sContext, httpStack);
and write your own implementation of HttpClientStack where you change the case of "Method.POST:" in the method createHttpRequest(). You also have to create an Object like "OwnHttpDelete" as extention of HttpEntityEnclosingRequestBase to use the method setEntityIfNonEmptyBody().
public class OwnHttpClientStack extends com.android.volley.toolbox.HttpClientStack {
private final static String HEADER_CONTENT_TYPE = "Content-Type";
public OwnHttpClientStack(HttpClient client) {
super(client);
}
#Override
public HttpResponse performRequest(Request<?> request, Map<String, String> additionalHeaders)
throws IOException, AuthFailureError {
HttpUriRequest httpRequest = createHttpRequest(request, additionalHeaders);
addHeaders(httpRequest, additionalHeaders);
addHeaders(httpRequest, request.getHeaders());
onPrepareRequest(httpRequest);
HttpParams httpParams = httpRequest.getParams();
int timeoutMs = request.getTimeoutMs();
// TODO: Reevaluate this connection timeout based on more wide-scale
// data collection and possibly different for wifi vs. 3G.
HttpConnectionParams.setConnectionTimeout(httpParams, 5000);
HttpConnectionParams.setSoTimeout(httpParams, timeoutMs);
return mClient.execute(httpRequest);
}
private static void addHeaders(HttpUriRequest httpRequest, Map<String, String> headers) {
for (String key : headers.keySet()) {
httpRequest.setHeader(key, headers.get(key));
}
}
static HttpUriRequest createHttpRequest(Request<?> request, Map<String, String> additionalHeaders) throws AuthFailureError {
switch (request.getMethod()) {
case Request.Method.DEPRECATED_GET_OR_POST: {
byte[] postBody = request.getPostBody();
if (postBody != null) {
HttpPost postRequest = new HttpPost(request.getUrl());
postRequest.addHeader(HEADER_CONTENT_TYPE, request.getPostBodyContentType());
HttpEntity entity;
entity = new ByteArrayEntity(postBody);
postRequest.setEntity(entity);
return postRequest;
} else {
return new HttpGet(request.getUrl());
}
}
case Request.Method.GET:
return new HttpGet(request.getUrl());
case Request.Method.DELETE:
OwnHttpDelete deleteRequest = new OwnHttpDelete(request.getUrl());
deleteRequest.addHeader(HEADER_CONTENT_TYPE, request.getBodyContentType());
setEntityIfNonEmptyBody(deleteRequest, request);
return deleteRequest;
case Request.Method.POST: {
HttpPost postRequest = new HttpPost(request.getUrl());
postRequest.addHeader(HEADER_CONTENT_TYPE, request.getBodyContentType());
setEntityIfNonEmptyBody(postRequest, request);
return postRequest;
}
case Request.Method.PUT: {
HttpPut putRequest = new HttpPut(request.getUrl());
putRequest.addHeader(HEADER_CONTENT_TYPE, request.getBodyContentType());
setEntityIfNonEmptyBody(putRequest, request);
return putRequest;
}
case Request.Method.HEAD:
return new HttpHead(request.getUrl());
case Request.Method.OPTIONS:
return new HttpOptions(request.getUrl());
case Request.Method.TRACE:
return new HttpTrace(request.getUrl());
case Request.Method.PATCH: {
HttpPatch patchRequest = new HttpPatch(request.getUrl());
patchRequest.addHeader(HEADER_CONTENT_TYPE, request.getBodyContentType());
setEntityIfNonEmptyBody(patchRequest, request);
return patchRequest;
}
default:
throw new IllegalStateException("Unknown request method.");
}
}
private static void setEntityIfNonEmptyBody(HttpEntityEnclosingRequestBase httpRequest,
Request<?> request) throws AuthFailureError {
byte[] body = request.getBody();
if (body != null) {
HttpEntity entity = new ByteArrayEntity(body);
httpRequest.setEntity(entity);
}
}
private static class OwnHttpDelete extends HttpPost {
public static final String METHOD_NAME = "DELETE";
public OwnHttpDelete() {
super();
}
public OwnHttpDelete(URI uri) {
super(uri);
}
public OwnHttpDelete(String uri) {
super(uri);
}
public String getMethod() {
return METHOD_NAME;
}
}
}

Related

Android multiple input q parameters in Google Translate API , with volley java

How to send multiple q input texts? As I see, the API doesn't allow q[] type arrays, instead it uses multiple q parameters.
protected Map<String,String> getParams(){
List<String> textString = new ArrayList<>();
Map<String,String> params = new HashMap<String, String>();
params.put("key", "key");
params.put("target", "DE");
params.put("q", text);
return params;
}
};
I found the following helper class:
class HttpParams extends HashMap<String, List<String>> {
private static final long serialVersionUID = 1L;
public HttpParams() {
super();
}
public HttpParams(int capacity) {
super(capacity);
}
public HttpParams(Map<String, List<String>> map) {
super(map);
}
public HttpParams(int capacity, float loadFactor) {
super(capacity, loadFactor);
}
/*
* This is the method to use for adding post parameters
*/
public void add(String key, String value) {
if (containsKey(key)) {
get(key).add(value);
}
else {
ArrayList<String> list = new ArrayList<String>();
list.add(value);
put(key, list);
}
}
/**
* Converts the Map into an application/x-www-form-urlencoded encoded string.
*/
public byte[] encodeParameters(String paramsEncoding) {
StringBuilder encodedParams = new StringBuilder();
try {
for (Map.Entry<String, List<String>> entry : entrySet()) {
String key = URLEncoder.encode(entry.getKey(), paramsEncoding);
for (String value : entry.getValue()) {
encodedParams.append(key);
encodedParams.append('=');
try {
encodedParams.append(URLEncoder.encode(value, paramsEncoding));
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
encodedParams.append('&');
}
}
return encodedParams.toString().getBytes(paramsEncoding);
} catch (UnsupportedEncodingException uee) {
throw new RuntimeException("Encoding not supported: " + paramsEncoding, uee);
}
}
}
and then in Main class that extends Request overrided the getBody():
public void volleyPost(String text,OnServiceResponseListener onServiceResponseListener){
String URL = "Your Url here";
RequestQueue requestQueue = Volley.newRequestQueue(this);
HttpParams mParams = new HttpParams();
mParams.add("key", "key");
mParams.add("target", "languageCode");
String wordsArray [] = text.split(",");
for(int i = 0;i<wordsArray.length;i++) {
mParams.add("q", wordsArray[i]);
}
StringRequest stringRequest = new StringRequest(Request.Method.POST, URL,
new Response.Listener<String>() {
#Override
public void onResponse(String response) {
onServiceResponseListener.onSuccess(response);
}
},
new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
onServiceResponseListener.onFailed(error.getMessage());
}
}){
#Override
public byte[] getBody() throws AuthFailureError {
if (mParams != null && mParams.size() > 0) {
Log.d(TAG,"mParams--->"+new Gson().toJson(mParams));
return mParams.encodeParameters(getParamsEncoding());
}
return null;
}
};
requestQueue.add(stringRequest);
}

Volley Authorization Required

I am trying to convert Unirest
HttpResponse<String> response = Unirest.post("https://api.tap.company/v2/charges")
.header("authorization", "Bearer sk_test_XKokBfNWv6FIYuTMg5sLPjhJ")
.header("content-type", "application/json")
.body("{\"amount\":1,\"currency\":\"KWD\",\"receipt\":{\"email\":false,\"sms\":true},\"customer\":{\"first_name\":\"test\",\"phone\":{\"country_code\":\"965\",\"number\":\"50000000\"}},\"source\":{\"id\":\"src_kw.knet\"},\"redirect\":{\"url\":\"http://your_website.com/redirect_url\"}}")
.asString();
to Volley
RequestQueue queue = Volley.newRequestQueue(this);
String url = "https://api.tap.company/v2/charges";
StringRequest TapREQUEST = new StringRequest(Request.Method.POST, url, new Response.Listener<String>() {
#Override public void onResponse(String response) {
Log.w("OnResponse:", response);
}
}, new Response.ErrorListener() {
#Override public void onErrorResponse(VolleyError error) { error.printStackTrace(); }
}) {
#Override public Map<String, String> getHeaders() {
Map<String,String> headers = new HashMap<>();
headers.put("content-type", "application/json");
headers.put("authorization", "Bearer sk_test_XKokBfNWv6FIYuTMg5sLPjhJ");
//String auth = "Bearer " + Base64.encodeToString("sk_test_XKokBfNWv6FIYuTMg5sLPjhJ".getBytes(), Base64.DEFAULT);
//headers.put("authorization", auth);
return headers;
}
#Override protected Map<String,String> getParams() {
Map<String,String> params = new HashMap<>();
params.put("amount", String.valueOf(9.500));
params.put("currency","KWD");
params.put("receipt","{'email':false,'sms':true}");
params.put("customer",":{'first_name':'test','phone':{'country_code':'965','number':'50000000'}}");
params.put("source","{'id':'src_kw.knet'}");
params.put("redirect",":{'url':'http://ib7ar.com'}");
return params;
}
};
queue.add(TapREQUEST);
but I get
E/Volley: [396] BasicNetwork.performRequest: Unexpected response code 400 for https://api.tap.company/v2/charges
When I click on link I get
{"errors":[{"code":"2107","description":"Authorization Required"}]}
You have to set body parameters in different way. Let's create method returning correct string:
#NotNull
private JSONObject getJsonObject() {
JSONObject params = new JSONObject();
try {
params.put("amount", "1");
params.put("currency", "KWD");
JSONObject receipt = new JSONObject();
receipt.put("email", "false");
receipt.put("sms", "true");
params.put("receipt", receipt);
JSONObject customer = new JSONObject();
customer.put("first_name", "test");
JSONObject phone = new JSONObject();
phone.put("country_code", "965");
phone.put("number", "50000000");
customer.put("phone", phone);
params.put("customer", customer);
JSONObject id = new JSONObject();
id.put("id", "src_kw.knet");
params.put("source", id);
JSONObject url = new JSONObject();
url.put("url", "http://ib7ar.com");
params.put("redirect", url);
} catch (JSONException e) {
e.printStackTrace();
}
return params;
}
And now instead of getParams() you need getBody() method:
#Override
public byte[] getBody() {
try {
return getJsonObject().toString().getBytes("utf-8");
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
return null;
}
}

How do I make a call OK HttpRequest post from an isolated class using async?

I was using this in another place as async but I wanted to refactor to make it reusable, how can I reorganize the code in order to work as a consumable class?. It doesn't work if it's not async and the ip of the backend is well defined so it's not that. Any ideas?
public class HTTPRequestManager {
public static JSONArray fetchData(){
return null;
}
public static String postData(Context context, String url, String JSONData) {
return null;
}
/* #Override
protected Integer doInBackground(String... strings) {
try {
//1.create client Object
OkHttpClient client = new OkHttpClient();
//2.Define request being sent to server
RequestBody postData = RequestBody.create(MediaType.parse("application/json; charset=utf-8"), JSONData);
Request request = new Request.Builder()
.url(context.getResources().getString(R.string.backend_base_url) + url)
.post(postData)
.build();
//3.Transport the request and wait for response to process next
Response response = client.newCall(request).execute();
String resultData = response.body().string();
if (resultData.equals("OK")) {
} else {
//post failed
return "FAILED";
}
return resultData;
} catch (Exception e) {
Log.d("API_CONNECTION_ERROR", "Couldn't connect to the API");
return "API_CONNECTION_ERROR";
}
}*/
}
I used to have this annonymous class embeeded in another class and it works(it's a get request) but the problem is that it's not reusable in that way:
public class AsyncHttpTask extends AsyncTask<String, Void, Integer> {
URL url = null;
#Override
protected void onPreExecute() {
getActivity().setProgressBarIndeterminateVisibility(true);
}
#Override
protected Integer doInBackground(String... params) {
Integer result = 0;
HttpURLConnection urlConnection;
try {
url = new URL (getResources().getString(R.string.backend_base_url) +
"api/flrcks/user/id/0/latitude/3000/longitude/300/within/9999999999999999999999999");
urlConnection = (HttpURLConnection) url.openConnection();
int statusCode = urlConnection.getResponseCode();
// 200 represents HTTP OK
if (statusCode == 200) {
BufferedReader r = new BufferedReader(new InputStreamReader(urlConnection.getInputStream()));
StringBuilder response = new StringBuilder();
String line;
while ((line = r.readLine()) != null) {
response.append(line);
}
parseResult(response.toString());
result = 1; // Successful
} else {
result = 0; //"Failed to fetch data!";
}
} catch (Exception e) {
Log.d(TAG, e.getLocalizedMessage());
}
return result; //"Failed to fetch data!";
}
#Override
protected void onPostExecute(Integer result) {
// Download complete. Let us update UI
progressBar.setVisibility(View.GONE);
if (result == 1) {
adapter = new MyRecyclerAdapter_Nearby(getActivity(), feedsList);
mRecyclerView.setAdapter(adapter);
checkAdapterIsEmpty();
} else {
Toast.makeText(getActivity(), "Failed to fetch data!", Toast.LENGTH_SHORT).show();
t.setVisibility(View.VISIBLE);
}
}
private void parseResult(String result) {
try {
JSONObject response = new JSONObject(result);
JSONArray posts = response.getJSONArray("rows");
feedsList = new ArrayList<>();
JSONArray members;
for (int i = 0; i < posts.length(); i++) {
memberList = new ArrayList<>();
final JSONObject post = posts.optJSONObject(i);
members=post.getJSONArray("members");
final FeedItem item = new FeedItem();
//for (int i = 0; i < posts.length(); i++) {
//JSONObject post = posts.optJSONObject(i);
//FeedItem item = new FeedItem();
item.setId(post.optString("id"));
item.setTitle(post.optString("name"));
item.setDescription(post.optString("description"));
item.setPrivacy(post.optString("privacy_mode_description"));
item.setInitial_date(post.optString("initial_date"));
item.setThumbnail(post.optString("thumbnail"));
item.setColor_hex(post.optString("color_hex"));
item.setTag(post.optString("tag"));
item.setDistance(post.optInt("st_distance"));
//item.setThumbnail(post.optString("thumbnail"));
for(int k=0; k <members.length();k++)
{
MemberItem memberItem = new MemberItem();
JSONObject member = members.optJSONObject(k);
memberItem.setName(member.optString("name"));
memberItem.setUsername(member.optString("username"));
memberItem.setProfile_pic(member.optString("profile_pic"));
memberItem.setIs_moderator(member.optBoolean("is_moderator"));
memberItem.setFacebookId(member.optString("facebook_id"));
memberList.add(memberItem);
}
item.setMemberList(memberList);
feedsList.add(item);
}
}
catch (JSONException e) {
e.printStackTrace();
}
}
}
What changes do I need to make to put it in an isolated file to be consumed by the whole app like for example in a file called OkHTTPRequests.class???
Create an interface
public interface OnWebResponseListener {
void onWebResponse(CommonUtilities.services service, String result);
}
create a public enum for identifying service. in my case i created a CommonUtilities java where i declared
public enum services {
LOGIN
}
Your Common File
public class CallAddr extends AsyncTask<String, Void, String> {
CommonUtilities.services service;
OnWebResponseListener onWebResponseListener;
String url;
FormBody.Builder body;
Request request;
OkHttpClient client;
final static String TAG = "CallAddr";
public CallAddr(Map<String, String> data, CommonUtilities.services service, OnWebResponseListener onWebResponseListener, String url) {
this.service = service;
this.onWebResponseListener = onWebResponseListener;
this.url = url;
body = new FormBody.Builder();
for (String key : data.keySet()) {
body.add(key, data.get(key));
}
client = new OkHttpClient();
}
#Override
protected String doInBackground(String... strings) {
String result = "";
request = new Request.Builder().url(url).post(body.build()).build();
try {
Response response = client.newCall(request).execute();
result = response.body().string();
} catch (Exception e) {
Log.e(TAG,Log.getStackTraceString(e));
}
return result;
}
#Override
protected void onPostExecute(String s) {
super.onPostExecute(s);
if (onWebResponseListener != null) {
onWebResponseListener.onWebResponse(service, s);
}
}
}

Unable to mimmick POSTMAN request in Volley

I am new to using Volley on Android. Using the old http client stuff I could make my web requests perfectly with the various headers and parameters, now I am unable. My request looks like this in Postman:
POST /token HTTP/1.1
Host: my.api.co.za
Accept: application/json
Content-Type: application/x-www-form-urlencoded
Cache-Control: no-cache
username=test&password=1234&grant_type=password
Yet I am unable to recreate and execute this request in Volley. I have tried making a custom Json request class that extends Request<JSONObject> but to no avail. Please see my code below:
public class CustomJsonRequest extends Request<JSONObject> {
private Response.Listener<JSONObject> listener;
private Map<String, String> params;
public CustomJsonRequest(int method, String url, Listener<JSONObject> responseListener, ErrorListener errorListener) {
super(method, url, errorListener);
this.listener = responseListener;
}
#Override
public Map getHeaders() throws AuthFailureError {
Map headers = new HashMap();
headers.put("Accept", "application/json");
headers.put("Content-Type", "application/x-www-form-urlencoded");
return headers;
}
#Override
public byte[] getBody() throws AuthFailureError {
HashMap<String, String> params = new HashMap<String, String>();
params.put("username", "test");
params.put("password", "1234");
params.put("grant_type", "password");
if (params != null && params.size() > 0) {
return encodeParameters(params, getParamsEncoding());
}
return null;
}
/**
* Converts <code>params</code> into an application/x-www-form-urlencoded encoded string.
*/
private byte[] encodeParameters(Map<String, String> params, String paramsEncoding) {
StringBuilder encodedParams = new StringBuilder();
try {
for (Map.Entry<String, String> entry : params.entrySet()) {
encodedParams.append(URLEncoder.encode(entry.getKey(), paramsEncoding));
encodedParams.append('=');
encodedParams.append(URLEncoder.encode(entry.getValue(), paramsEncoding));
encodedParams.append('&');
}
encodedParams.deleteCharAt(encodedParams.lastIndexOf("&"));
Log.e("params", encodedParams.toString());
return encodedParams.toString().getBytes(paramsEncoding);
} catch (UnsupportedEncodingException uee) {
throw new RuntimeException("Encoding not supported: " + paramsEncoding, uee);
}
}
#Override
protected Response<JSONObject> parseNetworkResponse(NetworkResponse response) {
try {
String jsonString = new String(response.data,
HttpHeaderParser.parseCharset(response.headers));
Log.e("response", response.toString());
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) {
// TODO Auto-generated method stub
Log.e("response", response.toString());
listener.onResponse(response);
}
private Priority mPriority;
public void setPriority(Priority priority) {
mPriority = priority;
}
#Override
public Priority getPriority() {
return mPriority == null ? Priority.NORMAL : mPriority;
}
}
And I call this as follows in my MainActivity class:
CustomJsonRequest request = new CustomJsonRequest(Request.Method.POST, AUTH_URL, new Response.Listener<JSONObject>() {
#Override
public void onResponse(JSONObject response) {
//showJSON(response);
VolleyLog.v("Response:%n %s", response);
}
}, new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
txtError(error);
}
});
Can somebody tell me where I am going wrong in creating this request?
You can try with my following sample code:
String url = "http://server/token";
Map<String, String> stringMap = new HashMap<>();
stringMap.put("grant_type", "password");
stringMap.put("username", "bnk");
stringMap.put("password", "bnk123");
Uri.Builder builder = new Uri.Builder();
Iterator entries = stringMap.entrySet().iterator();
while (entries.hasNext()) {
Map.Entry entry = (Map.Entry) entries.next();
builder.appendQueryParameter(entry.getKey().toString(), entry.getValue().toString());
entries.remove();
}
String requestBody = builder.build().getEncodedQuery();
JsonObjectRequest jsonObjectRequest = new JsonObjectRequest(Request.Method.POST, url, requestBody, new Response.Listener<JSONObject>() {
#Override
public void onResponse(JSONObject response) {
// do something...
}
}, new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
// do something...
}
}){
#Override
public String getBodyContentType() {
return "application/x-www-form-urlencoded";
}
};
UPDATE:
If your project uses Google's official volley as a module, you should add the following into JsonObjectRequest.java file:
public JsonObjectRequest(int method, String url, String requestBody,
Listener<JSONObject> listener, ErrorListener errorListener) {
super(method, url, requestBody, listener, errorListener);
}
UPDATE 2:
If you don't want to edit JsonObjectRequest.java file as I mentioned above, you can use the following code:
JsonObjectRequest jsonObjectRequest = new JsonObjectRequest(Request.Method.POST, url, null, new Response.Listener<JSONObject>() {
#Override
public void onResponse(JSONObject response) {
// do something...
}
}, new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
// do something...
}
}) {
#Override
public String getBodyContentType() {
return "application/x-www-form-urlencoded";
}
#Override
public byte[] getBody() {
// init parameters
Map<String, String> params = new HashMap<>();
params.put("grant_type", "password");
params.put("username", "bnk");
params.put("password", "bnk123");
// encode parameters (can use Uri.Builder as above)
String paramsEncoding = "UTF-8";
StringBuilder encodedParams = new StringBuilder();
try {
for (Map.Entry<String, String> entry : params.entrySet()) {
encodedParams.append(URLEncoder.encode(entry.getKey(), paramsEncoding));
encodedParams.append('=');
encodedParams.append(URLEncoder.encode(entry.getValue(), paramsEncoding));
encodedParams.append('&');
}
return encodedParams.toString().getBytes(paramsEncoding);
} catch (UnsupportedEncodingException uee) {
throw new RuntimeException("Encoding not supported: " + paramsEncoding, uee);
}
}
};
Hope it helps!

Android spring mobile rest template post request resulted in 400 (bad request) invoking error handler

I'm trying a simple post from Android to Spring MVC web service but I get
Post request for URL resulted in 400 (Bad request): invoking error handler org.springframework.web.client.HttpClientErrorException: 400 Bad Request
Here's my android code:
protected String doInBackground(MediaType... params) {
try{
HttpHeaders headers = new HttpHeaders();
headers.setContentType(MediaType.APPLICATION_JSON);
HttpEntity<?> requestEntity = new HttpEntity<Object>(postObject, headers);
RestTemplate restTemplate = new GzipJsonRestTemplate();
ResponseEntity<String> response = restTemplate.exchange(uri, HttpMethod.POST, requestEntity, String.class);
return response.getBody().toString();
}catch(Exception exp) {
fail = true;
exp.printStackTrace();
return null;
}
}
Here's my controller:
// New user registration
#RequestMapping(value = "/register", method = RequestMethod.POST, headers = "Content-Type=application/json")
public #ResponseBody Response register(#RequestBody User myNewUser) {
// TODO Check if user exists
Response response;
// Create new user
userService.addUser(myNewUser);
// Set response
response = new Response();
response.setResponseCode("0");
response.setMessage("success");
response.setContent(null);
return response;
}
What could be the issue?
Use MY class to
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.UnknownHostException;
import java.util.Map;
import org.apache.http.HttpResponse;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.DefaultHttpClient;
import org.json.JSONException;
import org.json.JSONObject;
import android.app.Activity;
import android.app.ProgressDialog;
import android.content.Context;
import android.os.AsyncTask;
import android.widget.Toast;
import com.ideal.assessmentapp_guj.utils.Applog;
public class Controller {
public static final String ERROR_UNKNOWN = "UNKNOWN_ERROR";
public static final String PARAMS_NAME = "params";
private Map<String, String> map;
private String jsonString;
private Context activity;
private AsyncTaskCompleteListener listener;
Exception exception;
private int requestCode;
private String key;
/**
*
* #param mContext
* #param map
*
* this constractor for only uploading data in background without
* showing any progress
*/
public Controller(Context mContext, Map<String, String> map,
AsyncTaskCompleteListener listener) {
if (IdealUtils.isNetworkAvailable(mContext)) {
this.map = map;
this.activity = mContext;
this.listener = listener;
AsyncHttpRequest request = new AsyncHttpRequest();
request.executeOnExecutor(AsyncHttpRequest.THREAD_POOL_EXECUTOR,
map.get("url"));
} else {
try {
if (activity != null)
Toast.makeText(
activity,
"Network Error – the application cannot connect to the internet. Please check your network connection.",
Toast.LENGTH_SHORT).show();
} catch (Exception e) {
}
}
}
public Controller(Activity con, Map<String, String> map,
AsyncTaskCompleteListener listener) {
this.map = map;
this.activity = con;
this.listener = listener;
// is Internet Connection Available...
if (IdealUtils.isNetworkAvailable(activity)) {
AsyncHttpRequest request = new AsyncHttpRequest();
request.executeOnExecutor(AsyncHttpRequest.THREAD_POOL_EXECUTOR,
map.get("url"));
// request.execute(map.get("url"));
} else {
Toast.makeText(
activity,
"Network Error – the application cannot connect to the internet. Please check your network connection.",
Toast.LENGTH_SHORT).show();
listener.onTaskCompleted(null, 0);
}
}
public Controller(Activity con, Map<String, String> map) {
this.map = map;
this.activity = con;
listener = (AsyncTaskCompleteListener) activity;
// is Internet Connection Available...
if (IdealUtils.isNetworkAvailable(activity)) {
AsyncHttpRequest request = new AsyncHttpRequest();
request.executeOnExecutor(AsyncHttpRequest.THREAD_POOL_EXECUTOR,
map.get("url"));
// request.execute(map.get("url"));
} else {
Toast.makeText(
activity,
"Network Error – the application cannot connect to the internet. Please check your network connection.",
Toast.LENGTH_SHORT).show();
listener.onTaskCompleted(null, 0);
}
}
public Controller(Activity con, Map<String, String> map, int requestID) {
this.map = map;
this.activity = con;
this.requestCode = requestID;
listener = (AsyncTaskCompleteListener) activity;
if (IdealUtils.isNetworkAvailable(activity)) {
// new AsyncHttpRequest().execute(map.get("url"));
AsyncHttpRequest request = new AsyncHttpRequest();
request.executeOnExecutor(AsyncHttpRequest.THREAD_POOL_EXECUTOR,
map.get("url"));
} else {
Toast.makeText(
activity,
"Network Error – the application cannot connect to the internet. Please check your network connection.",
Toast.LENGTH_SHORT).show();
listener.onTaskCompleted(null, requestID);
}
}
public Controller(Activity con, Map<String, String> map, int requestID,
String jsonString) {
this.map = map;
this.jsonString = jsonString;
this.activity = con;
this.requestCode = requestID;
listener = (AsyncTaskCompleteListener) activity;
if (IdealUtils.isNetworkAvailable(activity)) {
// new AsyncHttpRequest().execute(map.get("url"));
AsyncHttpRequest request = new AsyncHttpRequest();
request.executeOnExecutor(AsyncHttpRequest.THREAD_POOL_EXECUTOR,
map.get("url"));
} else {
Toast.makeText(
activity,
"Network Error – the application cannot connect to the internet. Please check your network connection.",
Toast.LENGTH_SHORT).show();
listener.onTaskCompleted(null, requestID);
}
}
public Controller(Activity con, String json, String url, int requestID) {
this.activity = con;
this.requestCode = requestID;
listener = (AsyncTaskCompleteListener) activity;
this.jsonString = json;
if (IdealUtils.isNetworkAvailable(activity)) {
new AsyncHttpRequest().execute(url);
} else {
Toast.makeText(
activity,
"Network Error – the application cannot connect to the internet. Please check your network connection.",
Toast.LENGTH_SHORT).show();
listener.onTaskCompleted(null, requestID);
}
}
class AsyncHttpRequest extends AsyncTask<String, Void, String> {
ProgressDialog pDialog;
#Override
protected void onPreExecute() {
}
#Override
protected String doInBackground(String... urls) {
String params = "obj";
if (map != null) {
map.remove("url");
params = map.get(PARAMS_NAME);
map.remove(PARAMS_NAME);
if (params == null) {
params = "obj";
}
}
HttpPost httppost = new HttpPost(urls[0]);
try {
HttpClient httpclient = new DefaultHttpClient();
JSONObject jsonObject = new JSONObject();
if (map != null) {
for (String key : map.keySet()) {
System.out.println(key + " < === > " + map.get(key));
try {
jsonObject.put(key, map.put(key, map.get(key)));
} catch (JSONException e) {
e.printStackTrace();
}
}
}
Applog.Log("json object", "jsonObject:" + jsonObject);
// httppost.setHeader("Content-Type", "application/json");
// httppost.setHeader("Accept", "application/json");
httppost.addHeader("Accept", "application/json");
httppost.addHeader("Content-type", "application/json");
if (jsonString == null) {
// httppost.setHeader("Content-Type", "application/json");
// httppost.setHeader("Accept", "application/json");
StringEntity se;
se = new StringEntity(
"{\""
+ params
+ "\":"
+ (map != null ? jsonObject.toString()
: jsonString) + "}");
// se.setContentEncoding("UTF-8");
Applog.Log(
"Post Data",
"{\""
+ params
+ "\":"
+ (map != null ? jsonObject.toString()
: jsonString) + "}");
httppost.setEntity(se);
} else {
Applog.Log("Controller", "Send Json as object");
StringEntity se;
se = new StringEntity(jsonString);
// se.setContentEncoding("UTF-8");
Applog.Log("Post Data",
"{\"obj\":"
+ (map != null ? jsonObject.toString()
: jsonString) + "}");
httppost.setEntity(se);
}
HttpResponse response = httpclient.execute(httppost);
BufferedReader inBuffer = new BufferedReader(
new InputStreamReader(response.getEntity().getContent()));
StringBuffer stringBuffer = new StringBuffer("");
String line = "";
String newLine = System.getProperty("line.separator");
while ((line = inBuffer.readLine()) != null) {
stringBuffer.append(line + newLine);
}
inBuffer.close();
// for (int i = 0; i < response.getAllHeaders().length; i++) {
// Applog.Log("HEADERS",
// "Response ::" + response.getAllHeaders()[i]);
// }
// Applog.Log("RESPONSE PARAMS", response.getStatusLine()
// .getStatusCode() + "");
String result = stringBuffer.toString();
// Applog.Log("Getting Result", "Result ::" + result);
return result;
// HttpResponse response = httpclient.execute(httppost);
//
// String responseBody = EntityUtils
// .toString(response.getEntity());
// return responseBody;
} catch (UnknownHostException e) {
e.printStackTrace();
exception = e;
// return ERROR_UNKNOWN;
} catch (ClientProtocolException e) {
exception = e;
e.printStackTrace();
// return ERROR_UNKNOWN;
} catch (IOException e) {
exception = e;
e.printStackTrace();
// return ERROR_UNKNOWN;
} catch (Exception e) {
exception = e;
e.printStackTrace();
// return ERROR_UNKNOWN;
}
return null;
}
#Override
protected void onPostExecute(String result) {
// if (null != pDialog && pDialog.isShowing()) {
// pDialog.dismiss();
// }
// if (result != null) {
if (listener != null) {
listener.onTaskCompleted(result, requestCode);
if (exception != null) {
listener.OnErrorFired(exception);
}
}
// }
super.onPostExecute(result);
}
}
}
HOW TO USE
Map<String, String> map = new HashMap<String, String>();
map.put("url", Urls.API_BACK_UP);
map.put("UserID", userID + "");
map.put("ProductID", 14 + "");
map.put("DeviceID", devideID);
map.put("TableName", TABLE_NAME_RESULT_MASTER);
map.put("BackIdentity", backRestoreIdentity + "");
map.put("TableData", uploadData);
new Controller(UtilityActivity.this, map, RESULTMASTER_UPLOAD_DONE);
also two three contractors are available. direct send json object use
Map<String, String> map = new HashMap<String, String>();
map.put("url", getLoginUrl());
JSONObject jsonObject = new JSONObject();
try {
jsonObject.put("UserName", username);
jsonObject.put("Password", password);
new Controller(this, map, 10, jsonObject.toString());
} catch (Exception e) {
e.printStackTrace();
}
Hope it helps...!

Categories