Java: Using GSon incorrectly? (null pointer exception) - java

I'm trying to get the hits of a google search from a string of the query.
public class Utils {
public static int googleHits(String query) throws IOException {
String googleAjax = "http://ajax.googleapis.com/ajax/services/search/web?v=1.0&q=";
String json = stringOfUrl(googleAjax + query);
JsonObject hits = new Gson().fromJson(json, JsonObject.class);
return hits.get("estimatedResultCount").getAsInt();
}
public static String stringOfUrl(String addr) throws IOException {
ByteArrayOutputStream output = new ByteArrayOutputStream();
URL url = new URL(addr);
IOUtils.copy(url.openStream(), output);
return output.toString();
}
public static void main(String[] args) throws URISyntaxException, IOException {
System.out.println(googleHits("odp"));
}
}
The following exception is thrown:
Exception in thread "main" java.lang.NullPointerException
at odp.compling.Utils.googleHits(Utils.java:48)
at odp.compling.Utils.main(Utils.java:59)
What am I doing incorrectly? Should I be defining an entire object for the Json return? That seems excessive, given that all I want to do is get one value.
For reference: the returned JSON structure.

Looking the returned JSON, it seems that you're asking for the estimatedResultsCount member of the wrong object. You're asking for hits.estimatedResultsCount, but you need hits.responseData.cursor.estimatedResultsCount. I'm not super familiar with Gson, but I think you should do something like:
return hits.get("responseData").get("cursor").get("estimatedResultsCount");

I tried this and it worked, using JSON and not GSON.
public static int googleHits(String query) throws IOException,
JSONException {
String googleAjax = "http://ajax.googleapis.com/ajax/services/search/web?v=1.0&q=";
URL searchURL = new URL(googleAjax + query);
URLConnection yc = searchURL.openConnection();
BufferedReader in = new BufferedReader(new InputStreamReader(
yc.getInputStream()));
String jin = in.readLine();
System.out.println(jin);
JSONObject jso = new JSONObject(jin);
JSONObject responseData = (JSONObject) jso.get("responseData");
JSONObject cursor = (JSONObject) responseData.get("cursor");
int count = cursor.getInt("estimatedResultCount");
return count;
}

Related

Inner object(ArrayList) is not converting to JSON String?

I am facing issue in converting the nested list object to JSON.I am using object mapper and it is only converting the starting values and after that there is one arraylist inside it and it is not going through that list.
I have tried some basic iteration using JsonNode root = mapper.valueToTree(obj)so that i can iterate through the inner arraylist but i am not getting the result.I am new to this parsing conversion.
code snippet--
public class JsonUtils {
public static <T> String toJsonString(final T obj) throws IOException {
final ObjectMapper mapper = new ObjectMapper();
String jsonString = null;
try {
//JsonNode root = mapper.valueToTree(obj);
jsonString = mapper.writeValueAsString(obj);
} catch (final JsonProcessingException e) {
throw e;
} catch (IOException e) {
throw e;
}
return jsonString;
}
public static <T> String toJsonString(final List<T> lstObject) throws JSONException, IOException {
final JSONArray jsonArray = new JSONArray();
for (final T object : lstObject) {
final String json = JsonUtils.toJsonString(object);
final JSONObject jsonObj = new JSONObject(json);
jsonArray.put(jsonObj);
}
return jsonArray.toString();
}
}
So here is the result which i am getting -
[2, [{"geoMarketId":1,"geoname":"AP","geoId":1,"checked":false},
{"geoMarketId":7,"geoname":"EP","geoId":2,"checked":false},
{"geoMarketId":16,"geoname":"Japan","geoId":3,"checked":true},
{"geoMarketId":18,"geoname":"LA","geoId":4,"checked":true},
{"geoMarketId":22,"geoname":"MEA","geoId":5,"checked":true},
{"geoMarketId":24,"geoname":"NA","geoId":6,"checked":false}]]
Actual Result which should come-
{"geoMarketId":1,"geoname":"AP","geoId":1,"checked":false,
marketName:{"marketname":JP,"marketname":"AP","marketname":MP}}
My json conversion is ignoring this inner list in the same index.
Is there any way my json class can iterate and also convert that innerlist to JSON?

Getting error "Expected BEGIN_OBJECT but was STRING at line 1" from a multi layer json

Here is the entire class:
public class Item {
static class Page {
Map <String,String> other_data;
Map <String,Map<String,List<Map<String,String>>>> specification;
}
public static String showName() throws Exception {
String json = Json.fetch(jsonurl);
Gson gson = new Gson();
Page result = gson.fromJson(json, Page.class);
return result.specification.get("result").get("feature").get(0).get("value");
// not working.
//return result.other_data.get("id"); <-- this one working
}
}
Here's how I fetch the json:
public class Json {
public static String fetch(String urlString) throws Exception {
BufferedReader reader = null;
try {
reader = new BufferedReader(new InputStreamReader(Connection.auth(urlString)));
StringBuffer buffer = new StringBuffer();
int read;
char[] chars = new char[1024];
while ((read = reader.read(chars)) != -1)
buffer.append(chars, 0, read);
//return buffer.toString();
return buffer.toString();
} finally {
if (reader != null)
reader.close();
}
}
}
I have been struggling to get a specific value from a mixed-type JSON feed using gson.
{
"other_data":{"id":"150","name":"AA"},
"specification":{"result":{"feature":[{"name":"attribute A","value":"50"}]}}
}
The feed should be valid since I can get 150 from other_data
`return result.other_data.get("id");`
However I can't get the value 50 from the first object of the array feature:
return result.specification.get("result").get("feature").get(0).get("value");
I'm receiving this error:
Expected BEGIN_OBJECT but was STRING at line 1 column 37948 path $.specification.
I think the declaration Map <String,Map<String,List<Map<String,String>>>> specification; is incorrect. I did a little debugging by changing it to Map <String,Object> specification. I managed to get the stringified object
{"feature":[{"name":"attribute A","value":"50"}]}
public class Item {
static class Page {
String page_type;
String name;
Map <String,String> submit_user_data;
Map <String,Object> specification;
}
public static String showName() throws Exception {
String json = Json.fetch(jsonurl);
Gson gson = new Gson();
Page td = gson.fromJson(json, Page.class);
return td.specification.get("result").toString(); // this one works!
}
}
Would anyone tell me what's wrong with the class getting the error?
Apparently escaping the json string solves the issue:
public static void main(String args[]) {
String json = "{\"other_data\":{\"id\":\"150\",\"name\":\"AA\"},\"specification\":{\"result\":{\"feature\":[{\"name\":\"attribute A\",\"value\":\"50\"}]}}}";
Gson gson = new Gson();
Page result = gson.fromJson(json, Page.class);
System.out.println(result.specification.get("result").get("feature").get(0).get("value"));
}

How to check if stream in twitch.tv is on?

Here is code of my getStream method:
public static Twitch_Stream getStream(String channelname) {
try {
String json = API.readJsonFromUrl("https://api.twitch.tv/kraken/streams?channel=" + channelname);
Twitch_Stream stream = new Twitch_Stream();
if (json.equalsIgnoreCase("[]")) {
stream.setOnline(false);
return stream;
}
JsonArray jb = gson.fromJson(json, JsonArray.class);
if (jb.size() != 0) {
JsonObject jo = (JsonObject) jb.get(0);
stream.setOnline(true);
stream.load(jo);
}
return stream;
} catch (Exception error) {
error.printStackTrace();
}
return null;
}
and here is code of Twitch_Stream class http://pastebin.com/3RX1L1cv
When I make something like this
Twitch_Stream streamer = Twitch_API.getStream("Jankos");
Bukkit.broadcastMessage("getName " + streamer.getName());
Bukkit.broadcastMessage(streamer.isOnline() + "");
streamer.getName() return null and streamer.isOnline() returns false, even when stream is on.
Where did I make a mistake?
I don't know what problem is in your code but simple workaround would be reading content from "https://api.twitch.tv/kraken/streams/" + channel which is JSON in format:
{
"_links" : {
//links to stream and channel
},
"stream" : {
//details about current stream
}
}
Now if value of stream key is null stream is off-line. If it is not null, it is on-line.
So your code can look like
public static void main(String[] argv) throws IOException {
System.out.println(checkIfOnline("Jankos"));
System.out.println(checkIfOnline("nightblue3"));
}
public static boolean checkIfOnline(String channel) throws IOException {
String channerUrl = "https://api.twitch.tv/kraken/streams/" + channel;
String jsonText = readFromUrl(channerUrl);// reads text from URL
JSONObject json = new JSONObject(jsonText);
return !json.isNull("stream");
}
private static String readFromUrl(String url) throws IOException {
URL page = new URL(url);
try (Stream<String> stream = new BufferedReader(new InputStreamReader(
page.openStream(), StandardCharsets.UTF_8)).lines()) {
return stream.collect(Collectors.joining(System.lineSeparator()));
}
}
I used JSONObject from org.json library. I am also using Java 8 and its streams.
If you want to use gson you can use instead something like
public static boolean checkIfOnline(String channel) throws IOException {
String channerUrl = "https://api.twitch.tv/kraken/streams/" + channel;
String jsonText = readFromUrl(channerUrl);// reads text from URL
JsonParser parser = new JsonParser();
JsonObject json = parser.parse(jsonText).getAsJsonObject();
return !json.get("stream").isJsonNull();
}
If you don't have Java 8 you can rewrite code reading text from URL to something like
private static String readFromUrl(String url) throws IOException {
URL page = new URL(url);
StringBuilder sb = new StringBuilder();
Scanner scanner = null;
try{
scanner = new Scanner(page.openStream(), StandardCharsets.UTF_8.name());
while (scanner.hasNextLine()){
sb.append(scanner.nextLine());
}
}finally{
if (scanner!=null)
scanner.close();
}
return sb.toString();
}
or from what I see you can use your API.readJsonFromUrl instead of readFromUrl.

Passing class as parameter in java function

I am trying to pass Java class as parameter in function, reason behind it it that I have several pojo classes for different APIs and I am trying to create a single parser utility for all the API URL and pojo class, I have tried with little or no success.
below is the code example -
public class util {
public static void main(String[] args) throws JsonParseException, JsonMappingException, IOException {
List<JsonGenMovies> jsongen = null;
String url = "http://www.dishanywhere.com/radish/v20/dol/movies/carousels/featured.json?nkey=0e1345ee597cf280c8a2cde367b6b894";
getMovieParser(jsongen, url);
List<JsonGenShow> jsongenShow = null;
String URL = "http://www.dishanywhere.com/radish/v20/dol/shows/carousels/featured.json";
getShowParser(jsongenShow, URL);
}
public static String[] getMovieParser (List<JsonGenMovies> jsongen, String url ) throws JsonParseException, JsonMappingException, IOException
{
URL jsonUrl = new URL(url);
ObjectMapper objmapper = new ObjectMapper();
jsongen = objmapper.readValue(jsonUrl, new TypeReference<List<JsonGenMovies>>() {});
String[] shows = new String [jsongen.size()];
int i = 0;
for(JsonGenMovies element : jsongen) {
shows[i++]=element.getName();
}
for(int j =0; j<shows.length;j++)
{
System.out.println(shows[j]);
}
return shows;
}
public static String[] getShowParser (List<JsonGen> jsongenShow, String URL ) throws JsonParseException, JsonMappingException, IOException
{
URL jsonUrl = new URL(URL);
ObjectMapper objmapper = new ObjectMapper();
jsongenShow = objmapper.readValue(jsonUrl, new TypeReference<List<JsonGen>>() {});
String[] shows = new String [jsongenShow.size()];
int i = 0;
for(JsonGen element : jsongenShow) {
shows[i++]=element.getName();
}
for(int j =0; j<shows.length;j++)
{
System.out.println(shows[j]);
}
return shows;
}
}
in the line -
jsongen = objmapper.readValue(jsonUrl, new TypeReference<List<JsonGen>>() {});
I still have <List<JsonGen>>a hard coded class name which I am trying to replace with arguments. please if you can help.
Please reply with little explanation, one liner might not be my thing.
Regards
Shek
If i understand correctly you want to have one function instead of two or more.
You can do that with generic type
E.g
public static <T> String[] getParser(List<T> jsongen, String url) throws JsonParseException, JsonMappingException, IOException {
URL jsonUrl = new URL(url);
ObjectMapper objmapper = new ObjectMapper();
jsongen = objmapper.readValue(jsonUrl, new TypeReference<List<T>>() {
});
String[] shows = new String[jsongen.size()];
int i = 0;
for (T element : jsongen) {
shows[i++] = element.getName();
}
for (int j = 0; j < shows.length; j++) {
System.out.println(shows[j]);
}
return shows;
}
If both JsonGenMovies and JsonGen extends/implements an interface or class, E.g JsonGenMovies extends Json then you can do this :
public static <T extends Json> String[] getParser(List<T> jsongen, String url)
T is a generic type, it does not really exist but it will be replaced at runtime by Class used for jsongen arg.
For example in :
List<String> myList;
getParser(myList, "http://blablabla.blalb.com");
All T are replaced by String.
I hope this is what you are looking for.
you can found more explanation about generic type here with better explanation than mine.
EDIT:
If you want to keep your POJO pattern then you can try this (not sure it will works)
public static String[] getParser(List<?> jsongen, String url) throws Exception {
URL jsonUrl = new URL(url);
ObjectMapper objmapper = new ObjectMapper();
jsongen = objmapper.readValue(jsonUrl, new TypeReference<List<?>>() {
});
String[] shows = new String[jsongen.size()];
int i = 0;
for (Object element : jsongen) {
Method method = element.getClass().getMethod("getName");
shows[i++] = (String) method.invoke(element);
}
for (int j = 0; j < shows.length; j++) {
System.out.println(shows[j]);
}
return shows;
}

Java JSON reading from URL

I'm trying to use my weather API to get the weather condition for an area, I think I have everything functioning except for the data parsing part.
import java.net.*;
import java.io.*;
import com.google.gson.*;
public class URLReader {
public static URL link;
public static void main(String[] args) {
try{
open();
read();
}catch(IOException e){}
}
public static void open(){
try{
link = new URL("http://api.wunderground.com/api/54f05b23fd8fd4b0/geolookup/conditions/forecast/q/US/CO/Denver.json");
}catch(MalformedURLException e){}
}
public static void read() throws IOException{
//little bit stuck here
}
}
Can anyone help me to finish this simple little project, I'm a beginner btw.
You can use javaQuery to do this more easily:
$.getJSON("http://api.wunderground.com/api/54f05b23fd8fd4b0/geolookup/conditions/forecast/q/US/CO/Denver.json", null, new Function() {
#Override
public void invoke($ j, Object... args) {
//if you are expecting a JSONObject, use:
JSONObject json = (JSONObject) args[0];
//otherwise, it would be: JSONArray json = (JSONArray) args[0];
//Then to more easily parse the JSON, do this:
Map<String, ?> map = $.map(json)
//if you are using an array instead, you can use: Object[] array = $.makeArray(json);
//Now just iterate through your map (or list) to get the data you want to parse.
}
});
Just open connection from URL and try to read JSON from it:
public static void read() throws IOException{
InputStream is = null;
try {
is = link.openConnection().getInputStream();
Reader reader = new InputStreamReader(is);
Map<String, String> jsonObj = gson.fromString(reader, new TypeToken<Map<String, String>>() {}.getType());
//TODO do next stuff
} finally{
if (is != null){
is.close();
}
}
}
If you want, you can bind jsonObj into whatever you want, please read documentation.

Categories

Resources