How to get variable's value from Gson - java

First, im a begiiner in GSON so please bear with me.
I have a set of classes with this structure :
class Response
Data data;
class Data
List<Item> items;
class Item
String id;
String title;
Private Player;
class Player
String mobile;
Im using those class to retrieve the JSON with GSON library.
I successfully retrieve the JSON data with this code :
Gson gson = new Gson();
Response myResponse = gson.fromJson(inputStreamReader, Response.class);
When i debug the code, i can see the Item class value is successfully retrieved inside the myResponse. However, i have a problem when i want to access the title variable in the Item Class because all i have is a Response Class.
How to get the title variable in the Item Class?
Any help is apprciated, Thanks for your help.

If you have public attributes (which is usually a bad practice!) you can just do:
//This will iterate over all items
for (Item item : myResponse.data.items) {
//for each item now you can get the title
String title = myItem.title;
}
Anyway, as I said, you should make your attributes private, and have getters and setters for those attributes. That's Java basics!
Namely, in your Response class, you should have something like:
private Data data;
public Data getData(){
return this.data;
}
public void setData(Data data){
this.data = data;
}
In the same way, you should have private attributes and getters and setters in all your classes.
So now you can access your items in the proper way with:
//Get the Data object with the getter method
Data data = myResponse.getData();
for (Item item : data.getItems()) {
String title = myItem.getTitle();
}

You can fetch the data like this:-
Data myData = myResponse.getData();
for(Item myItem : myData.getItems()){
// myItem.getTitle(); will give you the title from each Item
}
This is assuming that you've getters for all the fields in the classes.

Related

Java Gson Deserialization of selected fields from a list inside an object

I'm trying to figure out a way to selectively de-serialize specific fields from flickr.
{"photos":{"page":1,"pages":10,"perpage":100,"total":1000,"photo":[{"id":"","owner":"","secret":"","server":"","farm":,"title":"","ispublic":,"isfriend":,"isfamily":0,"url_s":"","height_s":"","width_s":""},...]}
I receive an object that contains two lists (photos and photo) and i would like to model in Java only the id, url_s and title from photo.
I figured out that I can create my java module with #expose annotation for the fields i'm interested in and than use
builder.excludeFieldsWithoutExposeAnnotation();
this way I'll control which fields get deserialized from photo (still not sure it's gonne work that way), but what about photos?
My questions are:
Is there a way to ignore that list? do I have to model a Java class that contains two lists (with their respective fields) just to grab what I need from the second list?
expanding upon the former question, if my module class for photo is:
public class GalleryItem {
#Expose()
private String mCaption;
#Expose()
private String mId;
#Expose()
private String mUrl;
}
can i call gson only on the part i need?
Type galleryListType = new TypeToken<ArrayList<GalleryItems>> (){}.getType();
List<GalleryItems> itemsList = gson.fromJson(jsonString, galleryListType);
can I somehow use setExclusionStrategies to skip the Photos list?
gsonBuilder.setExclusionStrategies(new ExclusionStrategy() {
#Override
public boolean shouldSkipField(FieldAttributes f) {
**return f.getName().contains("photos")**;
}
#Override
public boolean shouldSkipClass(Class<?> incomingClass) {
return ;
}
});
I've already implemented a solution using raw JSONObject/JSONArray but I'm curious regarding using GSON for the task at hand.
Thanks in advance!
Gson provides deserialisation on Java fields. If you mark as a transient your variable, Gson will not serialised to JSON. Gson also provides finer deserialisation control via annotations: #Expose(deserialize = false/true)
The last option would be writing your custom JsonDeserializer<T>

How to return partial entities/POJOs in Jersey REST api

I have a Java web service with a Jersey REST endpoint that returns a list of Restaurant POJOs as JSON objects (see Restaurant class below). The endpoint looks like this
/api/restaurants
and returns all the data tied to the Restaurant class. However, I want to add another, more lean endpoint that looks like this
/api/restaurants/name
which returns only the id and name of the Restaurant POJO for all restaurants. Is there a nice way to do this in Jersey out of the box (e.g. specify the fields you want from a POJO for specific endpoints)?
The corresponding POJO looks something like this:
#XmlRootElement
public class Restaurant {
// Members
private Long id;
private String name;
private List<Menu> menus;
...
// Constructors
public Restaurant() {}
...
// Getters and setters
...
}
If you need anything else, please don't hesitate to let me know! Thanks!
Yes, Jersey has support for selecting the elements that are included in serialized XML/JSON. Take a look at the entity filtering section of the manual.
Essentially, you annotate particular #XmlElements in your POJO with custom annotations. In your REST resource, you pass the annotation to Jersey when you build the Response.
Note that this only works if you use EclipseLink MOXy as your JAXB provider.
First of all, I am guessing that your api is going to be
/api/restaurants/{restaurantId}/name
and not
/api/restaurants/name
And in regards to your question of jersey having this feature out the box, I am not certain about it. Although, this is a much easier way to handle this.
Inside your POJO you can do something like this:
public class Restaurant {
// Members
private Long id;
private String name;
private List<Menu> menus;
...
// Constructors
public Restaurant() {}
...
// Getters and setters
...
// For getting only id and name
public Map getIdAndName()
{
Map<Object, Object> map = new HashMap<>();
map.put("id", this.id);
map.put("name", this.name);
return map;
}
// For getting just a list of menu and name
public Map getNameAndMenu()
{
Map<Object, Object> map = new HashMap<>();
map.put("menus", this.menus);
map.put("name", this.name);
return map;
}
And in your service class you can pretty much use something like this
#Path("/api/restaurants/{restaurantId}/name")
#Produces("application/json")
public String getRestaurantName(#PathParam("restaurantId") String restaurantId)
{
// GET RESTAURANT
Restaurant restaurant = getRestaurant(restaurantId);
Gson gson = new Gson();
// CONVERT TO JSON AND RETURN (or let jersey do that serializable, whichever way is preferable to you.
return gson.toJson(restaurant.getIdAndName());
}
Hope this helps!

Forming a JSON String using GSon

import java.util.HashMap;
public class JSON {
public String name;
public HashMap<String, String> Credentials = new HashMap<String, String>();
public JSON(String name){
Credentials.put(name, name);
}
}
JSON json = new JSON("Key1");
new Gson().toJson(json);
I get the following value as output.
{"Credentials":{"Key1":"Key1"}}
Now how would i create an JSONObject something like this below using Gson.
You create a POJO that matches your JSON data structure:
public class MyObject {
public HashMap<String,HashMap<String,String>> Credentials;
public HashMap<String, String> Header;
}
Edit for comments below:
This is kinda "data structures 101" but ... you have a JSON Object that boils down to a Hash table that contains two hash tables, the first of which contains two more hash tables.
You can represent this simply as I show above, or you could create all the POJOs and use those:
public class Credentials {
private PrimeSuiteCredential primeSuiteCredential;
private VendorCredential vendorCredential;
// getters and setters
}
public class PrimeSuiteCedential {
private String primeSuiteSiteId;
private String primeSuiteUserName;
...
// Getters and setters
}
public class VendorCredential {
private String vendorLogin;
...
// getters and setters
}
public class Header {
private String destinationSiteId;
...
// getters and setters
}
public class MyObject {
public Credentials credentials;
public Header header;
// getters and setters
}
Building on what #Brian is doing, you just need the auto serialization piece.
What you do is the following, and I have to state, this is with regard to a single object at the moment. You'll have to look through the GSON documentation for more detail on this if you're dealing with a collection of objects at the top level.
Gson gson= new Gson();
Writer output= ... /// wherever you're putting information out to
JsonWriter jsonWriter= new JsonWriter(output);
// jsonWriter.setIndent("\t"); // uncomment this if you want pretty output
// jsonWriter.setSerializeNulls(false); // uncomment this if you want null properties to be emitted
gson.toJson(myObjectInstance, MyObject.class, jsonWriter);
jsonWriter.flush();
jsonWriter.close();
Hopefully that will give you enough context to work with. Gson should be smart enough to figure out your properties and give them sensible names in the output.

How to convert HTTP Request Body into JSON Object in Java

I am trying find a Java lib/api that will allow me to turn the contents of a HTTP Request POST body into a JSON object.
Ideally I would like to use a Apache Sling library (as they are exposed in my container naturally).
The closest I've found it: org.apache.sling.commons.json.http which converts the header to JSON.
HTTP Post bodies are in the format; key1=value1&key2=value2&..&keyn=valueN so I assume there is something out there, but I havent been able to find it.
I may just have to use a custom JSONTokener (org.apache.sling.commons.json.JSONTokener) to do this if something doesn't already exist. Thoughts?
Thanks
Assuming you're using an HttpServlet and a JSON library like json-simple you could do something like this:
public JSONObject requestParamsToJSON(ServletRequest req) {
JSONObject jsonObj = new JSONObject();
Map<String,String[]> params = req.getParameterMap();
for (Map.Entry<String,String[]> entry : params.entrySet()) {
String v[] = entry.getValue();
Object o = (v.length == 1) ? v[0] : v;
jsonObj.put(entry.getKey(), o);
}
return jsonObj;
}
With example usage:
public void doPost(HttpServletRequest req, HttpServletResponse res) {
JSONObject jsonObj = requestParamsToJSON(req);
// Now "jsonObj" is populated with the request parameters.
// e.g. {"key1":"value1", "key2":["value2a", "value2b"], ...}
}
Jackson is also a good option - its used extensively in Spring. Here is the tutorial: http://wiki.fasterxml.com/JacksonInFiveMinutes
I recommend trying Apache Commons Beanutils.
ServeltRequest request;
Map map = request.getParameterMap();
MyObject object = new MyObject();
BeanUtils.populate(object, map);
String json = object.toJSON() //using any JSON library
Sorry on making this an own answer but obviously my reputation doesn't allow me to simply add a comment to the answer How to convert HTTP Request Body into JSON Object in Java of maerics.
I would also iterate over the request params but instead of using an arbitrary json library use the JSONObject that is provided by sling. http://sling.apache.org/apidocs/sling6/org/apache/sling/commons/json/JSONObject.html
import org.json.JSONObject;
JSONObject json = new JSONObject(request.getParameterMap())
Use Gson. With this you can create class with private variables which represent the data you want : for example.
meta:{
name:"Example"
firstname:"Example2"
}
data:[
{
title:"ecaetra"
description:"qwerty"
}
...
]
Json Object could be retrieve like this :
public class RetrieveData {
private Meta meta;
private List<Data> data;
public Meta getMeta(){
return meta;
}
public List<Data> getData(){
return data;
}
}
public class Meta {
private String name;
private String firstname;
public String getName(){
return name;
}
public String getFirstName(){
return firstname;
}
}
public class Data {
private String title;
private String description;
public String getTitle(){
return title;
}
public String getDescription(){
return description;
}
}
And your instruction are simple. Content is the content of your Page, you can retrieve it with Asynctask.
Object o = new Gson().fromJson(Content, RetrieveData.class);
data = (RetrieveData)o;
// Get Meta
data.getName(); // Example
data.getFirstName(); // Example2
// Get Data
data.get(0).getTitle(); // position 0 : ecaetra
data.get(0).getDescription(); // position 0 : qwerty

"Dotting" in JSON using Gson on Android

I'm trying to parse a JSON feed using Gson in Android. I know the JSON is valid. I suspect that it is because the format is like this:
"Info":[
{
"Id":"",
"Name":"",
"Description":"",
"Date":""
}
In order to parse this I need to "dot" in. Ex: Info.Name
How can I do this in a serialized DTO?
#SerializedName("Name")
public String name;
#SerializedName("Description")
public String desc;
#SerializedName("Date")
public String date;
I tried to put "Info." in front of each serializedName but that didn't work either. I also know my JSON parsing method works properly, because it's used somewhere else with a different DTO. But in that parsing, I don't have to "dotting" issue.
Can anyone help?
EDIT: I have tried everything you guys posted, and nothing works. The error says:
The JsonDeserializer failed to deserialize json object {"Info":[{".......
SECOND EDIT:
I was able to get rid of the error, but now it returns null. Haha, getting pretty damn frustrated right about now!
I am assuming that the actual JSON you are intaking is valid because the example you provided is not. In your JSON example, you have "Info":[ but there is no outer object containing the "Info" property, which is a must. The valid JSON would be:
{
"Info": [
{
"Id":"",
"Name":"",
"Description":"",
"Date":"",
}
]
}
This is a JSON object that has a property "Info" which has a value that is a list of objects. This list of objects contains one object that has the properties "Id", "Name", "Description", and "Date", all of which have empty-string values.
Here is a quick tutorial on how to use GSON to parse a JSON feed such as the above JSON:
You will need a class to represent the items in the list:
public class InfoItem {
public String Id;
public String Name;
public String Description;
public String Date;
public InfoItem() {}
}
And one to represent the list of Items:
public class InfoItemList extends LinkedList<InfoItem> {
public InfoItemList() { super() };
}
This added complexity is because GSON cannot otherwise get the type of a generic collection from the class data.
And one to represent the overall JSON message:
public class InfoMessage {
public InfoItemList Info;
public InfoMessage() {};
}
And then just:
gson.fromJson(jsonString, InfoMessage.getClass());
If just de-serializing a collection:
Type listType = new TypeToken<List<InfoItem>>() {}.getType();
gson.fromJson(jsonString2, listType);
The Info object is a list because of the []. You have to use the following code to deserialze it:
EDIT:
public class Info {
// as in your question
public String name;
...
}
public class Data {
#SerializedName("Info")
public List<Info> info;
}
Then just use the data class to deserialize your json.

Categories