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

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.

Related

StackOverflowError because JSONTokener

I am trying to transform a json file received through REST API into a list of java objects. Everything works well until couple runnings when I get StackOverFlow error.If I am not calling that method everything works well. I do not have any idea of how to solve this. Thank you
The error is :
Exception in thread "main" java.lang.StackOverflowError
at org.json.JSONTokener.nextClean(JSONTokener.java:292)
at org.json.JSONTokener.nextValue(JSONTokener.java:422)
at org.json.JSONObject.<init>(JSONObject.java:225)
at org.json.JSONTokener.nextValue(JSONTokener.java:431)
at org.json.JSONObject.<init>(JSONObject.java:244)
at org.json.JSONTokener.nextValue(JSONTokener.java:431)
at org.json.JSONArray.<init>(JSONArray.java:124)
at org.json.JSONTokener.nextValue(JSONTokener.java:434)
at org.json.JSONObject.<init>(JSONObject.java:244)
at org.json.JSONTokener.nextValue(JSONTokener.java:431)
at org.json.JSONObject.<init>(JSONObject.java:244)
at org.json.JSONTokener.nextValue(JSONTokener.java:431)
at org.json.JSONArray.<init>(JSONArray.java:124)
at org.json.JSONTokener.nextValue(JSONTokener.java:434)
at org.json.JSONObject.<init>(JSONObject.java:244)
The method that calls the REST Api is :
public List<Student> getAllStudents() {
try {
DefaultHttpClient httpClient = new DefaultHttpClient();
HttpGet getRequest = new HttpGet(
"http://localhost:8080/students/getAllStudents" +
"");
getRequest.addHeader("accept", "application/json");
HttpResponse response = httpClient.execute(getRequest);
if (response.getStatusLine().getStatusCode() != 200) {
throw new RuntimeException("Failed : HTTP error code : "
+ response.getStatusLine().getStatusCode());
}
BufferedReader br = new BufferedReader(
new InputStreamReader((response.getEntity().getContent())));
String output;
System.out.println("Output from Server .... \n");
ObjectMapper objMap = new ObjectMapper();
Student tabusca = new Student();
output = br.readLine();
tabusca = objMap.readValue(output, Student.class);
System.out.println(tabusca.toString());
String file = "";
while ((output = br.readLine()) != null) {
file += output;
//System.out.println(output);
}
//System.out.println(file);
JSONArray jsonArray= new JSONArray(file);
List<Student> list = new ArrayList<Student>();
for(int i=0; i<jsonArray.length(); i++) {
Student p = new Student();
p.setStudentId(jsonArray.getJSONObject(i).getLong("studentId"));
p.setEmail(jsonArray.getJSONObject(i).getString("email"));
p.setPassword(jsonArray.getJSONObject(i).getString("password"));
p.setFullname(jsonArray.getJSONObject(i).getString("fullname"));
p.setGrupa(jsonArray.getJSONObject(i).getLong("grupa"));
p.setHobby(jsonArray.getJSONObject(i).getString("hobby"));
p.setToken(jsonArray.getJSONObject(i).getString("token"));
p.setAssigmentStudent(null);
p.setAttendances(null);
p.setStudentUid(null);
list.add(p);
}
httpClient.getConnectionManager().shutdown();
return list;
} catch (ClientProtocolException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
return null;
}
The issue is your JSON is too 'deep'. There are too many nested elements in your json. The org.json parser gets too many recursive method calls to it resulting into Stackoverflow.
Even if you change your json library, you may still run in same problem.
To solve the issue you should either reconsider the JSON structure or increase the JRE stack size using jvm argument eg -Xss4m

JSONObject["name"] not a string

I've been trying for the last couple hours to fix this. I'm a little rusty when it comes to Java and decided I wanted to finish this method where I'm trying to parse the json to get the name of a map.
private static void mapLookUp (String mapId){
HttpClient httpclient = HttpClients.createDefault();
try
{
URIBuilder builder = new URIBuilder("https://www.haloapi.com/metadata/h5/metadata/maps");
URI uri = builder.build();
HttpGetWithEntity request = new HttpGetWithEntity(uri);
request.addHeader("ocp-apim-subscription-key", "aa09014c153b4a4b9c3a4937356e208a");
// Request body
StringEntity reqEntity = new StringEntity("{body}");
request.setEntity(reqEntity);
HttpResponse response = httpclient.execute(request);
HttpEntity entity = response.getEntity();
if (entity != null)
{
String response2request = EntityUtils.toString(entity);
//System.out.println(response2request.length()+"\n"+response2request);
String jsonString = "{\"Results\":"+response2request+"}";
System.out.println(jsonString);
JSONObject jsonResult = new JSONObject(jsonString);
List<String> mapName = new ArrayList<String>();
List<String> mapIds = new ArrayList<String>();
JSONArray array = jsonResult.getJSONArray("Results");
for(int i = 0 ; i < array.length() ; i++){
mapName.add(array.getJSONObject(i).getString("name"));
mapIds.add(array.getJSONObject(i).getString("id"));}
for(int i = 0 ; i < mapIds.size() ; i++)
if(mapIds.get(i).equals(mapId))
System.out.println("The most recent game was on "+mapName.get(i));
}
else
System.out.println("NULL");
}
catch (Exception e)
{
System.out.println("Caught exception");
System.out.println(e.getMessage());
}
}
In the output I get JSONObject["name"] not a string.
check JSON source. It seems like it may have no " around name value, or name is an object.
as example something like:
...
"name":John Doe,
...
or
"name":{"first":"John", "last":"Doe"},
...
BTW: Second is more expected. First must fail before, because it is wrong JSON. Value with no " around must be a number. But maybe name is empty like:
...
"name":,
...

400 - Bad Request on Apache POST sending JSON

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

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");

What's the recommended way to get the HTTP response as a String when using Apache's HTTP Client? [duplicate]

This question already has answers here:
How to get HttpClient returning status code and response body?
(5 answers)
Closed 2 years ago.
I've just begun using Apache's HTTP Client library and noticed that there wasn't a built-in method of getting the HTTP response as a String. I'm just looking to get it as as String so that i can pass it to whatever parsing library I'm using.
What's the recommended way of getting the HTTP response as a String? Here's my code to make the request:
public String doGet(String strUrl, List<NameValuePair> lstParams) {
String strResponse = null;
try {
HttpGet htpGet = new HttpGet(strUrl);
htpGet.setEntity(new UrlEncodedFormEntity(lstParams));
DefaultHttpClient dhcClient = new DefaultHttpClient();
PersistentCookieStore pscStore = new PersistentCookieStore(this);
dhcClient.setCookieStore(pscStore);
HttpResponse resResponse = dhcClient.execute(htpGet);
//strResponse = getResponse(resResponse);
} catch (ClientProtocolException e) {
throw e;
} catch (IOException e) {
throw e;
}
return strResponse;
}
You can use EntityUtils#toString() for this.
// ...
HttpResponse response = client.execute(get);
String responseAsString = EntityUtils.toString(response.getEntity());
// ...
You need to consume the response body and get the response:
BufferedReader br = new BufferedReader(new InputStreamReader(httpresponse.getEntity().getContent()));
And then read it:
String readLine;
String responseBody = "";
while (((readLine = br.readLine()) != null)) {
responseBody += "\n" + readLine;
}
The responseBody now contains your response as string.
(Don't forget to close the BufferedReader in the end: br.close())
You can do something like:
Reader in = new BufferedReader(
new InputStreamReader(response.getEntity().getContent(), "UTF-8"));
Using the reader you will be able to build your string. But if you are using SAX you can give the stream to the parser directly. This way you will not have to create the string and your memory footprint will be lower too.
In terms of conciseness of code it might be using the Fluent API like this:
import org.apache.http.client.fluent.Request;
[...]
String result = Request.Get(uri).execute().returnContent().asString();
The documentation warns though that this approach is not ideal in terms of memory consumption.

Categories