400 - Bad Request on Apache POST sending JSON - java

I'm trying to make a REST call from my class using the Apache. But its giving the 400 exception when I print the response of the REST service. Kindly find the code below and let me know the changes that needs to be made to make it working,
List<NameValuePair> pickup = new ArrayList<NameValuePair>();
ArrayList<HashMap> pickupItemList = new ArrayList<HashMap>();
String [] productIds = prop.getArray("vproductIDs");
String [] quantities = prop.getArray("vquantities");
String [] tprices = prop.getArray("vtprices");
String [] bprices = prop.getArray("vbprices");
HashMap pickupObjMap = new HashMap<String, Object>();
pickupObjMap.put("loyaltyId",prop.getString("loyaltyId"));
pickupObjMap.put("loyaltyFName",prop.getString("loyaltyFName"));
pickupObjMap.put("orderId",prop.getString("orderId"));
pickupObjMap.put("locationId",prop.getString("locationId"));
pickupObjMap.put("consignmentId",prop.getString("consignmentId"));
pickupObjMap.put("description",prop.getString("description"));
pickupObjMap.put("retailerId",prop.getString("retailerId"));
pickupObjMap.put("pickupType",Integer.parseInt(prop.getString("pickupType")));
pickupObjMap.put("email",prop.getString("email"));
pickupObjMap.put("loyaltyLName",prop.getString("loyaltyLName"));
pickupObjMap.put("status",prop.getString("status"));
for(int i=0; i<productIds.length ; i++){
HashMap map = new HashMap<String, Object>();
map.put("sku", productIds[i]);
map.put("quantity", Double.parseDouble(quantities[i]));
map.put("totalPrice", Double.parseDouble(tprices[i]));
map.put("basePrice", Double.parseDouble(bprices[i]));
pickupItemList.add(map);
}
pickup.add(new BasicNameValuePair("pickupItemList", pickupItemList.toString()));
pickup.add(new BasicNameValuePair("pickupObj", pickupObjMap.toString()));
pickup.add(new BasicNameValuePair("ovclid", prop.getString("ovclid")));
HttpPost httppost = new HttpPost("Target URL");
try {
httppost.setEntity(new UrlEncodedFormEntity(pickup));
httppost.setHeader("Content-Type", "application/json");
HttpClient httpclient = new DefaultHttpClient();
HttpResponse response = httpclient.execute(httppost);
HttpEntity entity = response.getEntity();
BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(entity.getContent()));
if (bufferedReader != null) {
int cp;
StringBuilder sb = new StringBuilder();
while ((cp = bufferedReader.read()) != -1) {
sb.append((char) cp);
}
System.out.println("String Response......."+sb);
bufferedReader.close();
}
System.out.println("Response......."+entity.getContent());
} catch (Exception e) {
e.printStackTrace();
}
Below is the response that I get upon making the REST Call.
Unexpected character ('p' (code 112)): expected a valid value (number, String, array, object, 'true', 'false' or 'null')
at [Source: org.glassfish.jersey.message.internal.EntityInputStream#175d5e8a; line: 1, column: 2]

Unexpected character "P" as in "POST", looks like the server returns html instead of json. Can you check server logs and see any exception? What is the return type - it should be json
post.setHeader("Content-type", "application/json");
If you are using glassfish you may have stumbled upon this bug https://netbeans.org/bugzilla/show_bug.cgi?id=231159

Related

HttpClient POST request returns status 200 without any body (however it should be). Length of the content is -1

I use Apache HttpClient for POST requests to web service.
I'm getting
httpResult=200
however there is no body. I know that some body should be there as when I
use another POST call method then I'm getting the body in JSON format.
At this method the length of the response body = -1.
response.getEntity().getContentLength() = -1;
The result of EntityUtils.toString(response.getEntity()) is empty string.
The code is:
CloseableHttpClient client = HttpClients.createDefault();
HttpPost httpPost = new HttpPost(url);
JSONObject attributes = new JSONObject();
JSONObject main = new JSONObject();
attributes.put("201", "Frank");
main.put("attributes", attributes);
main.put("primary", "2");
String json = main.toString();
StringEntity entity = new StringEntity(json);
httpPost.setEntity(entity);
httpPost.setHeader("Accept", "application/json");
httpPost.setHeader("Content-type", "application/json");
CloseableHttpResponse response = client.execute(httpPost);
httpResult = response.getStatusLine().getStatusCode();
client.close();
if (httpResult == HttpURLConnection.HTTP_OK) {
HttpEntity ent = response.getEntity();
Long length = ent.getContentLength();
System.out.println("Length: " + length);// length = -1
}
Could anyone give my some hint how to solve the issue?
In addition I would like to add the code that gives me a correct response body. At this case I use HttpURLConnection.
HttpURLConnection urlConnect = (HttpURLConnection) url.openConnection();
urlConnect.setConnectTimeout(10000);
urlConnect.setRequestProperty("Accept", "application/json");
urlConnect.setRequestProperty("Content-Type", "application/json");
urlConnect.setRequestMethod("POST");
JSONObject attributes = new JSONObject();
JSONObject main = new JSONObject();
attributes.put("201", "Frank");
main.put("primary", "2");
main.put("attributes", attributes);
urlConnect.setDoOutput(true);
OutputStreamWriter wr = new OutputStreamWriter(urlConnect.getOutputStream());
wr.write(main.toString());
wr.flush();
httpResult = urlConnect.getResponseCode();
System.out.println("Http Result: " + httpResult);
if (httpResult == HttpURLConnection.HTTP_OK) {
InputStream response = urlConnect.getInputStream(); // correct not empty response body
...
}
Please move the client.close(); to the end, i.e., after working with the response.
And to extract the response from HttpUrlConnection use the following
InputStream response = urlConnect.getInputStream();
BufferedReader br = new BufferedReader(new InputStreamReader(response));
StringBuilder sb = new StringBuilder();
String line;
while ((line = br.readLine()) != null) {
sb.append(line+"\n");
}
br.close();
JSONObject object = new JSONObject(sb.toString()); //Converted to JSON Object from JSON string - Assuming response is a valid JSON object.

How to get JSON Key/Value pairs with JSP [duplicate]

I'm very new to RESTFull WCF Services and even newer to calling them from an Android app. Here's my WCF service:
[ServiceContract]
public interface IPeople
{
[OperationContract]
void DoWork();
[WebGet(UriTemplate = "/GetPeople",
BodyStyle = WebMessageBodyStyle.WrappedRequest,
ResponseFormat = WebMessageFormat.Json,
RequestFormat = WebMessageFormat.Json)]
[OperationContract]
string GetPeople();
}
The implementation of the interface:
public string GetPeople()
{
PeoplesEntities qe = new PeoplesEntities();
var result = from q in qe.tPeople
select q;
int count = result.Count();
int index = new Random().Next(count);
tPeople people = result.OrderBy(a=>a.ID).Skip(index).FirstOrDefault();
// result.First().ToString();
return people.FirstName + " - " + people.LastName;
}
and this is how i'm consuming it through an android service:
try {
HttpGet request = new HttpGet(SERVICE_URI + "/GetPeople");
request.setHeader("Accept", "application/json");
request.setHeader("Content-type", "application/json");
DefaultHttpClient httpClient = new DefaultHttpClient();
HttpResponse response = httpClient.execute(request);
HttpEntity responseEntity = response.getEntity();
// Read response data into buffer
char[] buffer = new char[(int)responseEntity.getContentLength()];
InputStream stream = responseEntity.getContent();
InputStreamReader reader = new InputStreamReader(stream);
reader.read(buffer);
stream.close();
JSONArray plates = new JSONArray(new String(buffer));
return new String(buffer);
} catch (Exception e) {
e.printStackTrace();
return e.toString();
}
}
The exception I get is what is mentioned in the subject. What's strange is the value tha ti'm expecting is returned in the exception. I have no clue why it's expecting the square bracket.
FYI, most of the code i used is taken directly from online examples. Any help would be greatly appreciated. Thanks.
You're trying to create a JSONArray from a string that doesn't contain valid JSON array syntax. A JSONArray can be created from a string of the form [item1, item2, item3....] but you're just returning a single item in your string: FirstName LastName.
The line after it just returns the buffer, so the JSONArray call is pointless, anyway. You don't need the JSONArray call at all, since you're not dealing with JSON data. Just remove that line.

Code works in Xamarin Android but doestn't work in Java (HttpPost JSON)

I started developing in Xamarin, and then decided that license may be a bit expensive for playing around, so I'm transferring my code to java.
I have a small chunk that performs a POST with a JSON object, and it works in Xamarin and doest work in Java.
Xamarin:
var client = new HttpClient ();
var content = new FormUrlEncodedContent(new Dictionary<string, string>() {
{"action", "getEpisodeJSON"},
{"episode", "11813"}
});
client.DefaultRequestHeaders.Referrer = new Uri(link);
var resp = client.PostAsync("http://www.ts.kg/ajax", content).Result;
var repsStr = resp.Content.ReadAsStringAsync().Result;
dynamic res = JsonConvert.DeserializeObject (repsStr);
Android:
HttpClient httpclient = new DefaultHttpClient();
// 2. make POST request to the given URL
HttpPost httpPost = new HttpPost("http://www.ts.kg/ajax");
String json = "";
// 3. build jsonObject
JSONObject jsonObject = new JSONObject();
jsonObject.accumulate("action", "getEpisodeJSON");
jsonObject.accumulate("episode", "11813");
// 4. convert JSONObject to JSON to String
json = jsonObject.toString();
// 5. set json to StringEntity
StringEntity se = new StringEntity(json);
// 6. set httpPost Entity
httpPost.setEntity(se);
// 7. Set some headers to inform server about the type of the content
httpPost.setHeader("Accept", "application/json");
httpPost.setHeader("Content-type", "application/json");
httpPost.addHeader("Referer", "http://www.ts.kg");
// 8. Execute POST request to the given URL
HttpResponse httpResponse = httpclient.execute(httpPost);
// 9. receive response as inputStream
InputStream inputStream = httpResponse.getEntity().getContent();
// 10. convert inputstream to string
String result;
if(inputStream != null)
result = convertInputStreamToString(inputStream);
What is a correct way to make such a POST in Android?
UPD
Current problem is that i'm getting an empty result string;
private static String convertInputStreamToString(InputStream inputStream) throws IOException{
BufferedReader bufferedReader = new BufferedReader( new InputStreamReader(inputStream));
String line = "";
String result = "";
while((line = bufferedReader.readLine()) != null)
result += line;
inputStream.close();
return result;
}
I ended up catching all requests of my device via Fiddle (good tutorial is here: http://tech.vg.no/2014/06/04/how-to-monitor-http-traffic-from-your-android-phone-through-fiddler/)
The difference was in cookie, so I used and HttpContex variable as described here:
Android HttpClient Cookie
And I also had a different Content-Type, so I set this header manually as this:
httpPost.setHeader("Content-Type", "application/x-www-form-urlencoded");

settHeader ("content type", "") - confusion

I have a function with which I want to POST two variables to the php side, after these two variables match and the server processes the result, I want to return result in JSON. As of now my set header property looks like the following:
httppost.setHeader("Content-type", "application/json");
But while reading on at Wikipedia I found that the content type should be application/x-www-form-urlencoded and to accept JSON it should be Accept: application/json I want more clarity on this, how do I modify my code to achieve my desired result? As of now I am using local host and my POST variables seem to be not delivered on the php side. Following is my complete function:
public void parse(String last, String pwd){
String lastIndex = last;
DefaultHttpClient http = new DefaultHttpClient(new BasicHttpParams());
System.out.println("URL is: "+CONNECT_URL);
HttpPost httppost = new HttpPost(CONNECT_URL);
httppost.setHeader("Content-type", "application/json");
try{
List<NameValuePair> nameValuePairs = new ArrayList<NameValuePair>(2);
nameValuePairs.add(new BasicNameValuePair("key", password));
nameValuePairs.add(new BasicNameValuePair("last_index", lastIndex));
httppost.setEntity(new UrlEncodedFormEntity(nameValuePairs));
System.out.println("Post variables(Key): "+password+"");
System.out.println("Post variables(last index): "+lastIndex);
HttpResponse resp = http.execute(httppost);
HttpEntity entity = resp.getEntity();
ins = entity.getContent();
BufferedReader bufread = new BufferedReader(new InputStreamReader(ins, "UTF-8"), 8);
StringBuilder sb = new StringBuilder();
String line = null;
while((line = bufread.readLine()) != null){
sb.append(line +"\n");
}
result = sb.toString();
System.out.println("Result: "+result);
// readAndParseJSON(result);
}catch (Exception e){
System.out.println("Error: "+e);
}finally{
try{
if(ins != null){
ins.close();
}
}catch(Exception smash){
System.out.println("Squish: "+smash);
}
}
// return result;
}
You have a caps problem. Try "Content-Type" rather than "Content-type" (or use the const HTTP.CONTENT_TYPE).
It appears that your code is actually doing what that article describes, except that
// httppost.setHeader("Content-type", "application/json");
httppost.setHeader("Content-Type", "application/x-www-form-urlencoded");
httppost.setHeader("Accept", "application/json");
You are adding the x-www-form-urlencoded content here
httppost.setEntity(new UrlEncodedFormEntity(nameValuePairs));

how to set parameters to server from android application?

I have the following code to connect from my android application to zappos api server and search for some stuff. But It either returns error 404 or We are unable to process the request from the input feilds given.
When I execute the same query it works on the web browser.
The query is:
http://api.zappos.com/Search&term=boots&key=<my_key_inserted_here>
Code:
HttpClient client = new DefaultHttpClient();
HttpPost post = new HttpPost("http://api.zappos.com/Search");
NameValuePair keypair = new BasicNameValuePair("key",KEY);
NameValuePair termpair = new BasicNameValuePair("term",data);
List<NameValuePair> params = new ArrayList<NameValuePair>(2);
params.add(keypair);
params.add(termpair);
post.setEntity(new UrlEncodedFormEntity(params));
HttpResponse response = client.execute(post);
String str;
StringBuilder sb = new StringBuilder();
HttpEntity entity =response.getEntity();
if (entity != null) {
DataInputStream in = new DataInputStream(entity.getContent());
while (( str = in.readLine()) != null){
sb.append(str);
}
in.close();
}
Log.i("serverInterface","response from server is :"+sb.toString());
What am I doing wrong?
If I am correct, what you want to do is a GET request with parameters.
Then,the code would looks like something like that:
HttpClient client = new DefaultHttpClient();
HttpGet get = new HttpGet("http://api.zappos.com/Search");
HttpParams params = new BasicHttpParams();
params.setParameter("key", "KEY");
params.setParameter("term", "data");
get.setParams(params);
HttpResponse response;
response = client.execute(get);
String str;
StringBuilder sb = new StringBuilder();
HttpEntity entity = response.getEntity();
if (entity != null) {
DataInputStream in;
in = new DataInputStream(entity.getContent());
while ((str = in.readLine()) != null) {
sb.append(str);
}
in.close();
}
Log.i("serverInterface", "response from server is :" + sb.toString());
I found an answer to the question based on ALL of your help. I got the hint that I must search how to connect to REST service and I also used this result. This is the exact result I was looking for. Sadly it resembles too much to what I'm trying to achieve that I think whoever asked it might be applying to the same position :(

Categories