Getting additional info using Google's Gson - java

I have a program that I found on SO that allows the user to input a query and search using Google with whatever is inputted. The program then returns the first 4 results that Google gives. Here is the code:
public class TestGoogleSea {
public static void main(String[] args) throws IOException {
String address = "http://ajax.googleapis.com/ajax/services/search/web?v=1.0&q=";
String query = "who was the 19th president of america";
String charset = "UTF-8";
URL url = new URL(address + URLEncoder.encode(query, charset));
Reader reader = new InputStreamReader(url.openStream(), charset);
GoogleResults results = new Gson().fromJson(reader, GoogleResults.class);
int total = results.getResponseData().getResults().size();
System.out.println("total: "+total);
// Show title and URL of each results
for(int i=0; i<=total-1; i++){
System.out.println("Title: " + results.getResponseData().getResults().get(I).getTitle());
System.out.println("URL: " + results.getResponseData().getResults().get(I).getUrl() + "\n");
}
}
}
class GoogleResults{
private ResponseData responseData;
public ResponseData getResponseData() { return responseData; }
public void setResponseData(ResponseData responseData) { this.responseData = responseData; }
public String toString() { return "ResponseData[" + responseData + "]"; }
static class ResponseData {
private List<Result> results;
public List<Result> getResults() { return results; }
public void setResults(List<Result> results) { this.results = results; }
public String toString() { return "Results[" + results + "]"; }
}
static class Result {
private String url;
private String title;
public String getUrl() { return url; }
public String getTitle() { return title; }
public void setUrl(String url) { this.url = url; }
public void setTitle(String title) { this.title = title; }
public String toString() { return "Result[url:" + url +", title:" + title + "]"; }
}
}
For this specific case, (when the query is "who was the 19th president of america") the output is this:
Total: 4
Title: Rutherford B. Hayes - Wikipedia, the free encyclopedia
URL: http://en.wikipedia.org/wiki/Rutherford_B._Hayes
Title: List of <b>Presidents</b> of the United States - Wikipedia, the free <b>...</b>
URL: http://en.wikipedia.org/wiki/List_of_Presidents_of_the_United_States
Title: Rutherford B. Hayes | The White House
URL: http://www.whitehouse.gov/about/presidents/rutherfordbhayes
Title: <b>American President</b>: Rutherford Birchard Hayes - Miller Center
URL: http://millercenter.org/president/hayes
Now, if you were actually searching "who was the 19th president of america" on Google, in addition of list of the sites, you would see the picture of Rutherford B. Hayes with his name and the option to read "more about Rutherford B. Hayes". What I'm asking is if there is anyway I can get that information, the short little description of Hayes that Google got from Wikipedia most preferably as a string, or if that's not possible due to the limits of Gson?

Related

java.lang.IllegalStateExeption: Expectet a string but was BEGIN_ARRAY at line 1 column 16 path $[0].questions

I looked at some other threads about this topic and integrated the solution it offered but it still throws the same error. this is the first time i try to call an api on android. here i want to 'GET' an array of objects. There is no stack trace since the app does not crash. i think the problem has to do with the array of questions.
Retrofit retrofit = new Retrofit.Builder()
.baseUrl("http://192.168.1.100:3000/api/")
.addConverterFactory(GsonConverterFactory.create())
.build();
JsonPlaceHolderApi jsonPlaceHolderApi = retrofit.create(JsonPlaceHolderApi.class);
Call<List<Post>> call = jsonPlaceHolderApi.getPosts();
call.enqueue(new Callback<List<Post>>() {
#Override
public void onResponse(Call<List<Post>> call, Response<List<Post>> response) {
if (!response.isSuccessful()){
textViewResult.setText("Code: " + response.code());
return;
}
List<Post> posts = response.body();
for (Post post : posts){
String content = "";
content += "Doctor: " + post.getDoctor() + "\n";
content += "Name: " + post.getName() + "\n";
content += "Questions: " + post.getQuestions() + "\n\n";
textViewResult.append(content);
}
}
#Override
public void onFailure(Call<List<Post>> call, Throwable t) {
textViewResult.setText(t.getMessage());
}
});
here is an example of the json data:
[
{
"questions":[...],
"_id":"5f42954a7e252b48ec3564b6",
"name":"Lifestyle",
"doctor":"doctoremail#gmail.com",
"__v":0
},
{
"questions":[...],
"_id":"5f4299687e252b48ec3564b7",
"name":"Headache",
"doctor":"doctoremail#gmail.com",
"__v":0
},
{
"questions":[...],
"_id":"5f429b2f7e252b48ec3564b9",
"name":"Foot pain",
"doctor":"doctoremail#gmail.com",
"__v":0
}
]
I fixed it. the problem was that the 'questions' property in my model was of type string in stead of List String
package com.example.medlog;
import java.util.List;
public class Post {
private String name;
private String doctor;
private List<String> questions;
public String getName() {
return name;
}
public String getDoctor() {
return doctor;
}
public List<String> getQuestions() {
return questions;
}
}

google url shortening not working

Hi i'm making an app where user can send cards to other user but when i click send i'm trying to use url shortening to send link but my url shortening is not working at all it always shows the error message url shortening failed
I did some research on SO but did not get a proper solution
I know something is not right but dont know which part is not right
below is my code for url shortening
public void getShortenedUrl(String url, final int sendType){
try {
if (NetworkInfo.isNetworkAvailable(getActivity())) {
final boolean isMyCard=getArguments().getBoolean("isMyCard");
final String sharedTo=ceShareVia.getText().toString();
final String[] addresses = sharedTo.split(",");
LongUrl data = new LongUrl(url);
Call<LongUrl> cardResponseCall = ApiClientMain.getApiClient("https://www.googleapis.com/urlshortener/v1/")
.getShortenedUrl("application/json",ApplicationData.GOOGLE_URL_SHORTENER_KEY, data);
pbShare.setVisibility(View.VISIBLE);
cardResponseCall.enqueue(new retrofit2.Callback<LongUrl>() {
#Override
public void onResponse(Call<LongUrl> call, Response<LongUrl> response) {
pbShare.setVisibility(View.GONE);
if (response != null && response.body() != null) {
String url = response.body().getId();
String message;
if(isMyCard) {
message = "Hello," + "\n"
+ "Thanks for connecting!\n\n" + introMessage + "\n\n" + url + "\n\nRegards,\n"
+ preferenceManager.getPreferenceValues(PreferenceConstant.PERSON_NAME)
+ "\n" + "Have a nice day!";
}else {
message = "Hello," + "\n"
+ "Thanks for connecting!\n\n" + introMessageOther + "\n\n" + url + "\n\nRegards,\n"
+ preferenceManager.getPreferenceValues(PreferenceConstant.PERSON_NAME)
+ "\n" + "Have a nice day!";
}
switch (sendType){
case 0:
sendEmail(addresses,"My Business Card",message);
break;
case 1:
sendSms(sharedTo,message);
break;
case 2:
shareTextUrl(message);
break;
}
}
else {
Toast.makeText(getActivity(),"Url shortening failed",Toast.LENGTH_SHORT).show();
}
}
#Override
public void onFailure(Call<LongUrl> call, Throwable t) {
pbShare.setVisibility(View.GONE);
Toast.makeText(getActivity(),"Url shortening failed",Toast.LENGTH_SHORT).show();
}
});
}
} catch (Exception e) {
e.printStackTrace();
}
}
and here is model class for Long Url
public class LongUrl {
#SerializedName("longUrl")
#Expose
private String longUrl;
#SerializedName("id")
#Expose
private String id;
#SerializedName("kind")
#Expose
private String kind;
public String getLongUrl() {
return longUrl;
}
public void setLongUrl(String longUrl) {
this.longUrl = longUrl;
}
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public String getKind() {
return kind;
}
public void setKind(String kind) {
this.kind = kind;
}
public LongUrl(){
}
public LongUrl(String longUrl){
this.longUrl = longUrl;
}
}
Google URL Shortener is turned Down.
OFFICIAL RELEASE
Starting March 30, 2018, we will be turning down support for goo.gl URL shortener. From April 13, 2018 only existing users will be able to create short links on the goo.gl console. You will be able to view your analytics data and download your short link information in csv format for up to one year, until March 30, 2019, when we will discontinue goo.gl. Previously created links will continue to redirect to their intended destination.
Read this Blog for More Details.
If this is a New Project you cant create Shorten URL using the API

How to parse a JSONString and turn its values into an Array?

How to parse a JSONString, from a once JSONString.stringify simple array that now "appears flattened" inside, and turn its values back into a Java List or Java Array? (Using Jersey 1.x & Java) ? Array originally started as [1,2,3] before it was stringify-ed.
items = (3) [" To", "8357", "30028"] --> JSON.stringify(items) sent through rest call
Chrome Dev Tools's Request Payload after rest call:
items=%5B%22%C2%A0%C2%A0%C2%A0%C2%A0%C2%A0%C2%A0%C2%A0%C2%A0%C2%A0%C2%A0%C2%A0%C2%A0%C2%A0%C2%A0%C2%A0%C2%A0%C2%A0%C2%A0%C2%A0%C2%A0%C2%A0%C2%A0%C2%A0%C2%A0%C2%A0%C2%A0%C2%A0%C2%A0%C2%A0%C2%A0To%22%2C%228357%22%2C%2230028%22%5D
/*inside (Jersey) Rest Resource
#POST
#Path("/...")
#Consumes(MediaType.APPLICATION_JSON)
#Produces(MediaType.APPLICATION_JSON)
public Response receive(#Context SecurityContext securityContext, #Context
HttpServletRequest srequest, String jsonString) throws URISyntaxException,
JSONException ...
/*eclipse watch on jsonString inside (Jersey) Rest Resource
items=%5B%22%C2%A0%C2%A0%C2%A0%C2%A0%C2%A0%C2%A0%C2%A0%C2%A0%C2%A0%C2%A0%C2%A0%C2%A0%C2%A0%C2%A0%C2%A0%C2%A0%C2%A0%C2%A0%C2%A0%C2%A0%C2%A0%C2%A0%C2%A0%C2%A0%C2%A0%C2%A0%C2%A0%C2%A0%C2%A0%C2%A0To%22%2C%228357%22%2C%2230028%22%5D
*/[enter image description here][2]
NOTE: There is no name value. There is no entity.
There's only a very simple string of IDs because that's all I need. (Is that supported by Jersey 1.X or JAX-RS 1.X?)
JSONArray jSONArray = new JSONArray(java.util.Arrays.asList(jsonString));
Eclipse jSONArray Expression: jSONArray
--myArrayList
----elementData
------[0] "items=%5B%22%C2%A0%C2%A0%C2%A0%C2%A0%C2%A0%C2%A0%C2%A0%C2%A0%C2%A0%C2%A0%C2%A0%C2%A0%C2%A0%C2%A0%C2%A0%C2%A0%C2%A0%C2%A0%C2%A0%C2%A0%C2%A0%C2%A0%C2%A0%C2%A0%C2%A0%C2%A0%C2%A0%C2%A0%C2%A0%C2%A0To%22%2C%228357%22%2C%2230028%22%5D"
----------value
------------[0..99]
---------------[0] i
---------------1 t
---------------[2] e
---------------[3] m
---------------[4] s
---------------[5] =
---------------[6] %
---------------[7] 5
---------------[8] B ....
I cannot understand exactly your original question, but one of the way is:
import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;
import javax.swing.JFileChooser;
import org.json.simple.JSONObject;
import org.json.simple.parser.JSONParser;
public class JsonParser {
JFileChooser chooser = new JFileChooser();
File f;
static String fn = "";
static String js1 = "{\"name\": \"LALA\", \"email\": \"tst#tst.com\"}";
String name = "name";
String email = "email";
String fName = "firsName";
String city = "city";
// ... other needed fields
User u1 = null;
public JsonParser() {
parseFile();
System.out.println("\n" + u1.toShortString());
}
private String openFchooser() throws FileNotFoundException, IOException, InterruptedException, Exception {
int returnVal = chooser.showOpenDialog(null);
if (returnVal == JFileChooser.APPROVE_OPTION) {
f = chooser.getSelectedFile();
}
return f.getAbsolutePath();
}
// To parse JSON files with data
//===========================================
public void parseFile() {
JSONParser parser = new JSONParser();
try {
// To parse obj 1
Object obj1 = parser.parse(js1);
System.out.println("User 1: " + obj1.toString());
System.out.println();
JSONObject jobj1 = (JSONObject) obj1;
String from_name = jobj1.get(name).toString();
String from_email = jobj1.get(email).toString();
// String from_fName = jobj1.get(fName).toString();
// String from_city = jobj1.get(city).toString();
u1 = new User(from_name, from_email, null, null);
// System.out.println(u1.toString() + "\n");
} catch (Exception e) {
e.printStackTrace();
}
}
public static void main(String[] args) {
new JsonParser();
}
class User {
String name = null;
String email = null;
String fName = null;
String city = null;
public User(String n, String e, String f, String c) {
this.name = n;
this.email = e;
this.fName = f;
this.city = c;
}
public String getFirsName() {
return this.name;
}
public String setFirsName(String s) {
return this.name = s;
}
public String getEmail() {
return this.email;
}
public String setEmail(String s) {
return this.email = s;
}
public String toString() {
return "{\"name\":" + this.name + ", "
+ "\"email\":" + this.email + ", "
+ "\"firsName\":" + this.fName + ", "
+ "\"city\":" + this.city + "\"}";
}
public String toShortString() {
return "{\"name\": \"" + this.name + "\", "
+ "\"email\": \"" + this.email + "\"}";
}
};
}
OUTPUT:
User 1: {"name":"LALA","email":"tst#tst.com"}
{"name": "LALA", "email": "tst#tst.com"}
Thanks guys. I managed to find an alternative send & receive:
now sending array without stringify-ing it first
receiving with:
public Response archiveSelectedApplicants(#Context SecurityContext securityContext, #Context HttpServletRequest srequest,
#FormParam("items[]") List items) throws URISyntaxException

Gson not deserializing JSON data

I am trying to get some weather information from Yahoo APIs. This is my JSON:
JSON
This is my DTO:
public class forecast implements Serializable {
private static final long serialVersionUID = -520652416977871134L;
private String text;
private String high;
private String day;
private String code;
private String low;
private String date;
public forecast() {
}
public String getText() {
return text;
}
public void setText(String text) {
this.text = text;
}
public String getHigh() {
return high;
}
public void setHigh(String high) {
this.high = high;
}
public String getDay() {
return day;
}
public void setDay(String day) {
this.day = day;
}
public String getCode() {
return code;
}
public void setCode(String code) {
this.code = code;
}
public String getLow() {
return low;
}
public void setLow(String low) {
this.low = low;
}
public String getDate() {
return date;
}
public void setDate(String date) {
this.date = date;
}
#Override
public String toString() {
return "ClassPojo [text = " + text + ", high = " + high + ", day = "
+ day + ", code = " + code + ", low = " + low + ", date = "
+ date + "]";
}
}
I am only interested for the forecast element.
When I try to read the data de-serialized into my DTO all of them are null. I sense that I have not formatted my DTO properly.
Also, what Is the right way to map JSON to POJOs?
EDIT: this is my code for deserializing
String endpoint = "https://query.yahooapis.com/v1/public/yql?q=select%20*%20from%20weather.forecast%20"
+ "where%20woeid%20in%20(select%20woeid%20from%20geo.places(1)%20where%20text%3D%22Rhodes%2C%20Gr%22)&"
+ "format=json&env=store%3A%2F%2Fdatatables.org%2Falltableswithkeys";
try {
URL endpointURL = new URL(endpoint);
HttpURLConnection connection = (HttpURLConnection) endpointURL
.openConnection();
connection.connect();
InputStream input = connection.getInputStream();
JsonReader reader = new JsonReader(new InputStreamReader(input));
reader.setLenient(true);
forecast response = new Gson().fromJson(reader,
forecast.class);
Log.d("forecast", response.toString());//override toString() to return all the values of the object
} catch (IOException e) {
e.printStackTrace();
}
Your JSON (which you get from Yahoo) is very complex. So it can not be easily mapped to simple POJO (but you still can write huge POJO that contains fields for all corresponding nested JSON elements).
But it is possible to parse and extract specific elements from JSON.
The code:
public static void main(String[] args) {
String endpoint = "https://query.yahooapis.com/v1/public/yql?q=select%20*%20from%20weather.forecast%20"
+ "where%20woeid%20in%20(select%20woeid%20from%20geo.places(1)%20where%20text%3D%22Rhodes%2C%20Gr%22)&"
+ "format=json&env=store%3A%2F%2Fdatatables.org%2Falltableswithkeys";
try {
URL endpointURL = new URL(endpoint);
HttpURLConnection connection = (HttpURLConnection) endpointURL
.openConnection();
connection.connect();
InputStream input = connection.getInputStream();
JsonReader reader = new JsonReader(new InputStreamReader(input));
reader.setLenient(true);
JsonElement forecastSubObject = new JsonParser().parse(reader).
getAsJsonObject().get("query").
getAsJsonObject().get("results").
getAsJsonObject().get("channel").
getAsJsonObject().get("item").
getAsJsonObject().get("forecast");
System.out.println(forecastSubObject.toString());
List<forecast> forecasts = (List<forecast>)new Gson().fromJson(forecastSubObject, List.class);
System.out.println("forecast : " + forecasts);
System.out.println("first forecast: " + forecasts.get(0));
} catch (IOException e) {
e.printStackTrace();
}
}
Using JsonParser you can walk through elements (by theirs names). When 'forecast' element is reached corresponding string is extracted. Then it parsed as usual object and mapped to list of your forecast POJO.
Generally speaking mapping to/from JSON is very wide sphere. Different libraries provide different ways for achieving this (from simple and dirty to complex but reliable).

Google search API return false

I have tool code use Google search API.
My code:
import com.google.gson.Gson;
class GoogleResults {
private ResponseData responseData;
public ResponseData getResponseData() {
return responseData;
}
public void setResponseData(ResponseData responseData) {
this.responseData = responseData;
}
public String toString() {
return "ResponseData[" + responseData + "]";
}
static class ResponseData {
private List<Result> results;
public List<Result> getResults() {
return results;
}
public void setResults(List<Result> results) {
this.results = results;
}
public String toString() {
return "Results[" + results + "]";
}
}
static class Result {
private String url;
public String getUrl() {
return url;
}
public void setUrl(String url) {
this.url = url;
}
public String toString() {
return "Result[url:" + url + " ]";
}
}
}
public class CrawData {
public static void main(String[] args) throws IOException, InterruptedException {
String query;
int n;
int k=0;
String site;
String resultset;
Scanner st = new Scanner(System.in);
System.out.print(" Input key search: ");
query = st.nextLine();
System.out.print("Input site: ");
site = st.nextLine();
System.out.print("Input number of result: ");
n = st.nextInt();
resultset = query + " site:" + site;
for (int j = 0; j < n; j = j + 1) {
Thread.sleep(4000);
String address = "http://ajax.googleapis.com/ajax/services/search/web?v=1.0&start="+j+"&q=";
String charset = "UTF-8";
URL url = new URL(address + URLEncoder.encode(resultset, charset));
Reader reader = new InputStreamReader(url.openStream(), charset);
GoogleResults results = new Gson().fromJson(reader,
GoogleResults.class);
int total = results.getResponseData().getResults().size();
// Show title and URL of each results
for (int i = 0; i <= total - 1; i++) {
String Url = results.getResponseData().getResults().get(i)
.getUrl();
k = k+1;
System.out.println("URL: " +Url+ " " + k);
}
}
}
}
when i run it, i have trouble about result return of code.
My system return list url of website.. but it not stable.
Some picture:
my error
Have error: Exception in thread "main" java.lang.NullPointerException
at CrawData.main(CrawData.java:107)
help me...
Sorry my english is too bad.. :(
My guess is that on this line:
String Url = results.getResponseData().getResults().get(i)
.getUrl();
Either get(i) is returning null or getUrl() is returning null. You should add some error handling logic:
if (results.getResponseData().getResults().get(i) != null &&
results.getResponseData().getResults().get(i).getUrl() !=null) {
String Url = results.getResponseData().getResults().get(i)
.getUrl();
k = k+1;
System.out.println("URL: " +Url+ " " + k);
} else {
// Print some type of error here. Try to figure out why the result or the
// url is null
}

Categories

Resources