I am trying to send a request to the Grooveshark API using POST Payload and their requested methods, and I have found a problem. Allow me to show you my code first.
public void getResponse() throws Exception
{
if(service.equals("Grooveshark")) link += getHmacMD5(privateGroovesharkKey, jsonInfo.toString());
if(requestedMethod.equals("GET")) infoURL = new URL(link+arguments);
else infoURL = new URL(link);
HttpURLConnection connection = (HttpURLConnection) infoURL.openConnection();
connection.setRequestMethod(requestedMethod);
connection.setRequestProperty("Accept-Charset", "UTF-8");
connection.setDoOutput(true);
connection.setDoInput(true);
connection.setUseCaches(false);
if(service.equals("Grooveshark"))
{
connection.setRequestProperty("Content-Type","application/json");
OutputStream output = connection.getOutputStream();
output.write(jsonInfo.toString().getBytes());
}
else if(requestedMethod.equals("POST") || requestedMethod.equals("PUT"))
{
OutputStream output = connection.getOutputStream();
output.write(arguments.getBytes());
}
connection.connect();
BufferedReader rd = new BufferedReader(new InputStreamReader(connection.getInputStream()));
StringBuilder sb = new StringBuilder();
String line;
while ((line = rd.readLine()) != null)
sb.append(line).append('\n');
setJsonResult(sb.toString());
System.out.println(jsonResult);
jsonFinal = new JSONObject(jsonResult);
connection.disconnect();
}
I have got that code up here in my project, and I can successfully send requested to any API Webservice that uses JSON in their responses. Now there's only a problem: In Android, it does not give me the WHOLE answer. I've tried running the code on a separate Java (no Android) project, and I get the following output. Although, if I run it on Android, the Log shows me the following:
{"header":{"hostname":"RHL073"},"result":{"songs":[{"SongID":5443351,"SongName":"??????\u00b7???? (FINAL FANTASY XII????)","ArtistID":713,"ArtistName":"Final Fantasy","AlbumID":898007,"AlbumName":"Final Fantasy XII Original Soundtrack","CoverArtFilename":"","Popularity":1214500005,"IsLowBitrateAvailable":tr
And it stops on that tr. Has it anything to do with the parsing of the file that I actually apply afterwards? I don't think it is, but just in case, here it is [This is how I call the search, JSONHandler being the object that contains the code provided above]:
public void performSearch() throws Exception
{
JSONObject search = new JSONObject();
search.put("method", method);
JSONObject header = new JSONObject();
header.put("wsKey", key);
JSONObject parameters = new JSONObject();
parameters.put("query", getSearchQuery());
parameters.put("country", "Portugal");
parameters.put("limit", limit);
parameters.put("offset", "");
search.put("header", header);
search.put("parameters", parameters);
JSONHandler jsonHandler = new JSONHandler(link, search, "Grooveshark", "POST", "");
JSONObject finalResult = jsonHandler.getJsonFinal();
JSONArray songs = finalResult.getJSONObject("result").getJSONArray("songs");
ArrayList<Result> allResults = new ArrayList<Result>();
for(int i = 0; i < songs.length(); i++)
{
JSONObject inner = (JSONObject) songs.get(i);
String name = inner.getString("SongName");
int ID = inner.getInt("SongID");
String artist = inner.getString("ArtistName");
Result res = new Result(name, artist, ID);
res.setAlbumName(inner.getString("AlbumName"));
boolean low = inner.getBoolean("IsLowBitrateAvailable");
int bit = 0;
if(low) bit = 1;
else bit = 0;
res.setIsLowBitRateAvailable(bit);
}
setResults(allResults);
}
As you can clearly see, I am using the json.org library. I really don't understand what's the problem here. Has anyone got any idea as to why?
Related
public static String getsheetdata() throws IOException {
String name = null;
String email = null;
String phone = null;
String fin = null;
String address = null;
String car_registraion = null;
String question = null;
String pin = null;
String car_registraion_date = null;
String url = "https://sheets.googleapis.com/v4/spreadsheets/1BH-e3-XSZ9LjsQqELjZLpZbnB4DmIhrPy2VDAZsP9KM/values/lead!A2:J2?key=AIzaSyDJRy73ru1BSLFCb9nknUF8SlZd4LxwJAc";
URL obj = new URL(url);
HttpsURLConnection con = (HttpsURLConnection) obj.openConnection();
// optional default is GET
con.setRequestMethod("GET");
//add request header
con.setRequestProperty("User-Agent", "Mozilla/5.0 (Macintosh; U; Intel Mac OS X 10_5_8; en-US) AppleWebKit/532.5 (KHTML, like Gecko) Chrome/4.0.249.0 Safari/532.5");
int responseCode = con.getResponseCode();
System.out.println("\nSending 'GET' request to URL : " + url);
System.out.println("Response Code : " + responseCode);
BufferedReader in = new BufferedReader(
new InputStreamReader(con.getInputStream()));
String inputLine;
StringBuffer response = new StringBuffer();
while ((inputLine = in.readLine()) != null) {
response.append(inputLine);
}
in.close();
System.out.println(response.toString());
//Read JSON response and print
JSONObject myResponse = new JSONObject(response.toString());
return inputLine;
}
I am getting following response
Sending 'GET' request to URL : https://sheets.googleapis.com/v4/spreadsheets/1BH-e3-XSZ9LjsQqELjZLpZbnB4DmIhrPy2VDAZsP9KM/values/lead!A2:J2?key=AIzaSyDJRy73ru1BSLFCb9nknUF8SlZd4LxwJAc
Response Code : 200
{ "range": "lead!A2:J2", "majorDimension": "ROWS", "values": [ [ "Lead Data Set 1 - Normal FOC Lead", "Bhupendra", "bhupendra+283273#abc.com", "2389432432", "90909892098988771", "Street123, Berlin", "1289243424321", "no comments", "10115", "12 / 12 / 2017" ] ]}
I need to fill the response data in following variables .
String name = null;
String email = null;
String phone = null;
String fin = null;
String address = null;
String car_registraion = null;
String question = null;
String pin = null;
String car_registraion_date = null;
Would appreciate if anyone can help me on it.
You can use any JSON to Java unmarshalling library to convert the JSON to Java object. Check options and examples
Create JSONObject of the response string you are getting and then extract values fields from JSONObject as JSONArray and then traverse through that JSONArray to get list of your object.
To add to Hiren's answer, you can try (using org.json):
JSONObject myResponse = new JSONObject(response.toString());
JSONArray jsonArr = (JSONArray) myResponse.get("values");
JSONArray requiredValues = jsonArr.getJSONArray(0);
String[] values = new String[requiredValues.length()];
for (int i = 0; i < requiredValues.length(); i++) {
values[i] = requiredValues.getString(i);
}
Now the "values" part of response will be stored in String[] values
for (int j = 0; j < values.length; j++) {
System.out.println(values[j]);
}
This will print
Lead Data Set 1 - Normal FOC Lead
Bhupendra
bhupendra+283273#abc.com
2389432432
90909892098988771
Street123, Berlin
1289243424321
no comments
10115
12 / 12 / 2017
You can assign it accordingly. Hope it helps.
I am currently developing an app and need to parse JSON objects from inside an unnamed array.
I can only manage to parse JSON arrays with a name such as this one: http://jsonparsing.parseapp.com/jsonData/moviesDemoItem.txt.
The code that I used for the one above is
protected String doInBackground(String... params) {
HttpURLConnection connection = null;
BufferedReader reader = null;
try {
URL url = new URL(params[0]);
connection = (HttpURLConnection) url.openConnection();
connection.connect();
InputStream stream = connection.getInputStream();
reader = new BufferedReader(new InputStreamReader(stream));
StringBuffer buffer = new StringBuffer();
String line = "";
while ((line = reader.readLine()) != null) {
buffer.append(line);
}
String asd = buffer.toString();
JSONObject parentObject = new JSONObject(asd);
JSONArray parentArray = parentObject.getJSONArray("movies");
JSONObject fObject = parentArray.getJSONObject(0);
String movie = fObject.getString("movie");
int year = fObject.getInt("year");
return movie + year;
The code includes "movies" which is the array name .
What should I change to parse only the objects from within a JSON array such as https://restcountries.eu/rest/v1/all?
Your countries list is simply an array. Doesn't need a name.
Simply replace
JSONObject parentObject = new JSONObject(asd);
with
JSONArray parentObject = new JSONArray(asd);
See this post for how to iterate over that array to parse the remainder of the objects.
How to parse JSON in Android
Starting something like
for (int i=0; i < parentObject.length(); i++) {
Alternatively, Volley's JsonArrayRequest would be useful, or learning about Retrofit+Gson would be even better if you don't feel like manually parsing the JSON data yourself.
I am working on a Server-Client application. For part of the requests, I need to generate a piece of Json String on Server side and send it to Client. The Json String was generated correctly on the server side according to the Server log. But on the Android client side, the String was changed and cannot be parsed as correct Json String.
Here are some related code.
Generate Json String on Server side:
#RequestMapping(value="/resourceList/{actType}/{type}/{id}")
#ResponseBody public Object personList(#PathVariable int actType, #PathVariable int type, #PathVariable int id){
ArrayList<ItemBase> list = new ArrayList();
......
return new ArrayList();
}
This generates following Json code:
[{"countryID":1,"locationID":5,"siteID":5,"brief":"shark point","userID":0,"status":"normal","rank":0.0,"id":2,"timestamp":1471494991000,"displayName":"shark point","pic":"2.jpg","actType":1,"type":64},{"countryID":1,"locationID":5,"siteID":5,"brief":"halik","userID":0,"status":"normal","rank":0.0,"id":3,"timestamp":1471495034000,"displayName":"halik","pic":"3.jpg","actType":1,"type":64}]
And receive it on Android client:
......
HttpURLConnection urlConnection = null;
try {
URL url = new URL(request);
urlConnection = (HttpURLConnection) url.openConnection();
InputStream in = new BufferedInputStream(urlConnection.getInputStream());
byte[] buffer = new byte[256];
int len = 0;
StringBuilder responseBuilder = new StringBuilder();
while ((len = in.read(buffer)) != -1) {
String str = new String(buffer, "utf-8");
responseBuilder.append(str);
}
String response = responseBuilder.toString().trim();
The response variable was written with value:
[{"countryID":1,"locationID":5,"siteID":5,"brief":"halik","userID":0,"status":"normal","rank":0.0,"id":3,"timestamp":1471495034000,"displayName":"halik","pic":"3.jpg","actType":1,471494991000,"displayName":"shark point","pic":"2.jpg","actType":1,"type":64},{"countryID":1,"locationID":5,"siteID":5,"brief":"halik","userID":0,"status":"normal","rank":0.0,"id":3,"timestamp":1471495034000,""type":64}]":"halik","pic":"3.jpg","actType":1,471494991000,"displayName":"shark point","pic":"2.jpg","actType":1,"type":64},{"countryID":1,"locationID":5,"siteID":5,"brief":"halik","userID":0,"status":"normal","rank":0.0,"id":3,"timestamp":1471495034000,"
Which cannot be parsed as Json String correctly with obvious errors.
Most methods which return a Json String to client request work fine as I expected except this one. But this method was implemented almost exactly the same as those ones work correctly. Thus I have no idea how this happened at all. Any one got any clew please help.
You're building String the wrong way.
Try this instead:
// …
HttpURLConnection urlConnection = null;
try {
URL url = new URL(request);
urlConnection = (HttpURLConnection) url.openConnection();
InputStream in = new BufferedInputStream(urlConnection.getInputStream());
BufferedInputStream bis = new BufferedInputStream(in);
ByteArrayOutputStream buf = new ByteArrayOutputStream();
int result = bis.read();
while(result != -1) {
buf.write((byte) result);
result = bis.read();
}
String response = buf.toString();
// …
I'm trying to connect Android json output with Ruby web application.
I'm having difficulty to connect Android json post request with receiving from Ruby app. When Android jsonobject has another jsonobject inside, it is not recognised in the ruby app. Here is my code.
Android Code
JSONObject events_array = new JSONObject();
JSONObject parent=new JSONObject();
for (int i = 0; i < classtimeList.size(); i++) {
events_array.put(classtimeList.get(i).toString(),priorityList.get(i).toString());
}
parent.put("token","token_information");
parent.put("class_type", "something");
parent.put("class_frequency", "5");
parent.put("course_id", "20");
parent.put("events_array", events_array);
String urlParameters = "info="+parent.toString();
Log.i("parameters", urlParameters);
This is a log info for parameters.
info={"token":"token_information","class_type":"something","class_frequency":"5","course_id":"20","events_array":{"3074":"3","3134":"1","3140":"1","3146":"3","3152":"1","3075":"3","3076":"3","3077":"3","3078":"3","3079":"3","3216":"3","3217":"3","3218":"1","3219":"3"}}
I pass this information to Ruby app and I am having difficulty to extract "events_array" information. Below is my Ruby Code.
My full Android code looks like
class apply extends AsyncTask<String, String, String> {
ProgressDialog pd;
private Exception exception;
protected void onPreExecute() {
pd = new ProgressDialog(ClassApply2.this);
pd.setMessage("loading");
pd.show();
}
protected String doInBackground(String... args) {
String token = args[0];
try {
URL url = new URL("https://www.ringleplus.com/api/v1/apply/test");
HttpURLConnection connection = (HttpURLConnection) url.openConnection();
JSONObject events_array = new JSONObject();
JSONObject parent=new JSONObject();
for (int i = 0; i < classtimeList.size(); i++) {
events_array.put(classtimeList.get(i).toString(),priorityList.get(i).toString());
}
parent.put("token","token_information");
parent.put("class_type", "something");
parent.put("class_frequency", "5");
parent.put("course_id", "20");
parent.put("events_array", events_array);
connection.setRequestMethod("POST");
connection.setDoOutput(true);
String urlParameters = "info=" + parent.toString();
DataOutputStream dStream = new DataOutputStream(connection.getOutputStream());
dStream.writeBytes(urlParameters);
//dStream.write(data); // <!-- 여기에 url parameter가 들어감
dStream.flush();
dStream.close();
Log.i("parameters", parent.toString());
InputStream in = connection.getInputStream();
BufferedReader reader = new BufferedReader(new InputStreamReader(in));
StringBuffer buffer = new StringBuffer();
String line = "";
while ((line = reader.readLine()) != null) {
buffer.append(line).append("\n");
}
reader.close();
connection.disconnect();
JSONObject jsonObj = null;
jsonObj = new JSONObject(buffer.toString().trim());
String output = jsonObj.getString("item");
return output;
}
catch(Exception e) {
Log.e("ERROR", e.getMessage(), e);
return null;
}
}
protected void onPostExecute(String response) {
if(response == null) {
response = "THERE WAS AN ERROR";
}
//progressBar.setVisibility(View.GONE);
Log.i("INFO", response);
if (pd != null) {
pd.dismiss();
}
adapter.notifyDataSetChanged();
}
Ruby Code
post :test do
parsed_json = ActiveSupport::JSON.decode(params[:info].to_json)
token = parsed_json["token"]
events_array = parsed_json["events_array"]
output = Array.new
if events_array != nil
events_array.each do |start_time, priority|
if priority.to_i == 1 || priority.to_i == 2
userapply = Userapply.new
userapply.classtime_id = start_time
userapply.user_id = user.id
userapply.priority = priority
userapply.save
output << {:userapply_id => userapply.id, :classtime_id => userapply.classtime_id, :user_id => userapply.user_id, :priority => userapply.priority}
end
end
end
return {status: 'ok', item: events_array}
end
What it supposed to be returned is the information about events_array (i.e. {"3074":"3","3134":"1","3140":"1","3146":"3","3152":"1","3075":"3","3076":"3","3077":"3","3078":"3","3079":"3","3216":"3","3217":"3","3218":"1","3219":"3"} )
but, the Android output log is
I/INFO: events_array
but the token extraction seems working.
token = parsed_json["token"]
If this works, then my gut feeling is parsed_json["events_array"] also should work in some sense. But I'm not stuck here.
If this is resolved, then I want to receive parsed_json["events_array"] as a hash information and want to process the full code and get the "output" instead of events_array to check why this doesn't work.
Please let me know if there is anything I'm missing. I really need some help.
Looking forward to seeing anyone's reply.
I finally figured out where the problem came from. I compared what you send to your server with curl in comment above, and what you try to send from android. And these two things are completly difirent. To send the same from androdid, you should form your urlParameter like that:
JSONObject info = new JSONObject();
info.put("info",parent);
urlParameters = info.toString();
And don't forget to do connection.setRequestProperty("Content-Type", "application/json") after connection.setDoOutput(true).
I tested it outside android, and it returned pretty the same as curl command from your comment above. It should work just fine in android.
PS: Please, be more more attentive next time.
Will try to explain my question here.
I have a program that is suppose to parse through an incoming JSON-file that I receive from a web-crawler.
public static void Scan(Article article) throws Exception
{
//When running program, creates a error text-file inside java Project folder
File file = new File("errorlogg.txt");
FileWriter fileWriter = new FileWriter(file, true);
// if file doesn't exists, then create it
if (!file.exists())
{
file.createNewFile();
}
//Setting up an URL HttpURLConnection given DOI
URL urlDoi = new URL (article.GetElectronicEdition());
//Used for debugging
System.out.println("Initial DOI: " + urlDoi);
//Transform from URL to String
String doiCheck = urlDoi.toString();
//Redirect from IEEE Xplore toe IEEE Computer Society
if(doiCheck.startsWith("http://dx."))
{
doiCheck = doiCheck.replace("http://dx.doi.org/", "http://doi.ieeecomputersociety.org/");
urlDoi = new URL(doiCheck);
}
HttpURLConnection connDoi = (HttpURLConnection) urlDoi.openConnection();
// Make the logic below easier to detect redirections
connDoi.setInstanceFollowRedirects(false);
String doi = "{\"url\":\"" + connDoi.getHeaderField("Location") + "\",\"sessionid\":\"abc123\"}";
//Setting up an URL to translation-server
URL url = new URL("http://127.0.0.1:1969/web");
URLConnection conn = url.openConnection();
conn.setDoOutput(true);
conn.setRequestProperty("Content-Type", "application/json");
OutputStreamWriter writer = new OutputStreamWriter(conn.getOutputStream());
writer.write(doi);
writer.flush();
String line;
BufferedReader reader = new BufferedReader(new InputStreamReader(conn.getInputStream()));
while ((line = reader.readLine()) != null )
{
//Used to see of we get something from stream
System.out.println(line);
//Incoming is JSONArray, so create new array and parse fill it with incoming information
JSONArray jsonArr = new JSONArray(line);
JSONObject obj = jsonArr.getJSONObject(0);
//Check if names from DBLP is the same as translators get
//AuthorName, from field creators
JSONArray authorNames = obj.getJSONArray("creators");
ArrayList<Author> TranslationAuthors = new ArrayList<Author>();
Here is the bit of the code that I'm talking about. As you can see I wanna run this code when I get some information from the bufferreader.
My problem is that my program doesn't seem to skip when I don't get a valid JSON. Instead it runs to this line of code:
JSONArray authorNames = obj.getJSONArray("creators")
And then is forced to exit since it can't get the field "creators" since there is none.
How can I do to make sure that my program don't encounter this problem? How can I easy put it in the error-logg file that I create that I could't collect any information.
I think you are working with a org.json.JSONObject? If that's so, there is a has method, which can be used to avoid the JSONException in case the key does not exist.
JSONArray authorNames = null;
if (obj.has("creators")) {
authorNames = obj.getJSONArray("creators");
}