how to map value json to object java using jackson-annotations - java

I have a string Json :
{
   "title": "PowerPoint Presentation",
   "author": "Hana",
   "subject": null,
   "keywords": null,
   "created_date": "2016-03-25 15:11:17",
   "modified_date": "2016-03-28 17:27:06",
   "creator": null,
   "producer": "LibreOffice 5.0",
   "pdfversion": null,
   "file_size": 149225,
   "total_page": 24
}
and Object java
public class ContentInfo {
#JsonProperty("title")
private String title;
#JsonProperty("author")
private String author;
#JsonProperty("subject")
private String subject;
#JsonProperty("keywords")
private String keywords;
#JsonProperty("created_date")
private String createdDate;
#JsonProperty("modified_date")
private String modifiedDate;
// (application name that create original file of PDF)
#JsonProperty("creator")
private String creator;
// (application name that create PDF)
#JsonProperty("producer")
private String producer;
#JsonProperty("pdfversion")
private String pdfversion;
#JsonProperty("file_size")
private long fileSize;
#JsonProperty("total_page")
private long totalPage;
public ContentInfo() {
}
public ContentInfo(String title, String author, String subject, String keywords, String createdDate, String modifiedDate, String creator, String producer, String pdfversion, long fileSize, long totalPage, PageViewSetting page_view_setting) {
this.title = title;
this.author = author;
this.subject = subject;
this.keywords = keywords;
this.createdDate = createdDate;
this.modifiedDate = modifiedDate;
this.creator = creator;
this.producer = producer;
this.pdfversion = pdfversion;
this.fileSize = fileSize;
this.totalPage = totalPage;
this.page_view_setting = page_view_setting;
}
public String getTitle() {
return title;
}
public String getAuthor() {
return author;
}
public String getSubject() {
return subject;
}
public String getKeywords() {
return keywords;
}
public String getCreatedDate() {
return createdDate;
}
public String getModifiedDate() {
return modifiedDate;
}
public String getCreator() {
return creator;
}
public String getProducer() {
return producer;
}
public String getPdfversion() {
return pdfversion;
}
public long getFileSize() {
return fileSize;
}
public long getTotalPage() {
return totalPage;
}
public void setTitle(String title) {
this.title = title;
}
public void setAuthor(String author) {
this.author = author;
}
public void setSubject(String subject) {
this.subject = subject;
}
public void setKeywords(String keywords) {
this.keywords = keywords;
}
public void setCreatedDate(String createdDate) {
this.createdDate = createdDate;
}
public void setModifiedDate(String modifiedDate) {
this.modifiedDate = modifiedDate;
}
public void setCreator(String creator) {
this.creator = creator;
}
public void setProducer(String producer) {
this.producer = producer;
}
public void setPdfversion(String pdfversion) {
this.pdfversion = pdfversion;
}
public void setFileSize(long fileSize) {
this.fileSize = fileSize;
}
}
I am using the below code to map them :
ObjectMapper objectMapper = new ObjectMapper();
objectMapper.configure(DeserializationConfig.Feature.FAIL_ON_UNKNOWN_PROPERTIES, false);
data = objectMapper.readValue(this.jsonContentInfoData, ContentInfo.class);
However result ResponseBody is wrong in some field:
"content_info": {
"title": "PowerPoint Presentation"
"author": "Hana"
"subject": null
"keywords": null
"created_date": "2016-03-25 15:11:17"
"creator": null
"producer": "LibreOffice 5.0"
"pdfversion": null
"modified_date": "2016-03-28 17:27:06"
"file_size": 0
"total_page": 0
}

Jackson serializes and deserializes based on the access modifier of your field, in conjunction with the available and properly named getter and setter method.
You can override this feature to insure all private fields are ser/deserialized using:
mapper.setVisibility(PropertyAccessor.FIELD, Visibility.ANY);
However, it's decent for testing, but isn't the optimal solution.
Instead, you should in practice use private fields and use public getters/setters to control the serialization and deserialization process.
A public Getter Makes a Non-Public Field Serializable and Deserializable
Unintuitively, the getter also makes the private field deserializable as well – because once it has a getter, the field is considered a property.
A public Setter Makes a Non-Public Field Deserializable Only
In your code, showing the getters/setters:
setPdfversion - Is incorrect: Should be setPdfVersion
getTotalPage(long totalPage) - Is incorrect and is intended to be setTotalPage(long totalPage)
Finally, I think it will help to change the types of totalPage and fileSize from the primitive long to the wrapper object Long. Also change the getter/setters for these fields to match the Long types. Since both of these fields are having issues and are using primitives, it seems possible that Jackson (or your version of it) does not handle primitives.

Related

How do I deserialize a JSON representation containing array of objects using jackson?

I have the exact same JSON representation as here: https://newsapi.org/docs/endpoints/top-headlines
To deserialize this into java objects I have created a News and a Article class. News contains multiple Articles. So here are my classes:
News:
public class News {
private String status;
private int totalResults;
private Article[] articles;
public News() {
}
public News(String status, int totalResults, Article[] articles) {
this.status = status;
this.totalResults = totalResults;
this.articles = articles;
}
public String getStatus() {
return status;
}
public void setStatus(String status) {
this.status = status;
}
public int getTotalResults() {
return totalResults;
}
public void setTotalResults(int totalResults) {
this.totalResults = totalResults;
}
public Article[] getArticles() {
return articles;
}
public void setArticles(Article[] articles) {
this.articles = articles;
}
}
Article:
public class Article {
private String source;
private String author;
private String title;
private String description;
private String url;
private String imageUrl;
private String publishedAt;
private String content;
public Article() {
}
public Article(String source, String author, String title, String description, String url, String imageUrl,
String publishedAt, String content) {
this.source = source;
this.author = author;
this.title = title;
this.description = description;
this.url = url;
this.imageUrl = imageUrl;
this.publishedAt = publishedAt;
this.content = content;
}
public String getSource() {
return source;
}
public void setSource(String source) {
this.source = source;
}
public String getAuthor() {
return author;
}
public void setAuthor(String author) {
this.author = author;
}
public String getTitle() {
return title;
}
public void setTitle(String title) {
this.title = title;
}
public String getDescription() {
return description;
}
public void setDescription(String description) {
this.description = description;
}
public String getUrl() {
return url;
}
public void setUrl(String url) {
this.url = url;
}
public String getImageUrl() {
return imageUrl;
}
public void setImageUrl(String imageUrl) {
this.imageUrl = imageUrl;
}
public String getPublishedAt() {
return publishedAt;
}
public void setPublishedAt(String publishedAt) {
this.publishedAt = publishedAt;
}
public String getContent() {
return content;
}
public void setContent(String content) {
this.content = content;
}
}
Now I am using the com.fasterxml.jackson.databind.ObjectMapper as following to deserialize the JSON representation into a News object:
ObjectMapper objectMapper = new ObjectMapper();
News news = objectMapper.readValue(response.toString(), News.class);
Here I am getting a com.fasterxml.jackson.databind.exc.MismatchedInputException: Cannot deserialize instance of `java.lang.String` out of START_OBJECT token
The problem apparently is the array of articles representated in JSON.
I have read about arrays deserialization in jackson but I found nothing about deserialization of objects that contain properties AND array of objects. https://www.baeldung.com/jackson-deserialization
How do I do this properly using the ObjectMapper? Am I missing out on something? Any help is appreciated, thanks!
Your source mapping is wrong,
the source field is of format
source": {
"id": "google-news",
"name": "Google News"
}
this can be replaced with
public class Source {
private String id;
private String name;
public Source() {}
public Source(String id, String name) {
this.id = id;
this.name = name;
}
}
and replace
private String source;
with
private Source source;
in the Article class

how to convert Source type converter to room

I am developing a news app and implemented but I am not able to convert model class to typeconverter below my model class
#Entity
#ForeignKey(entity = Source.class,parentColumns = "source", childColumns = "content")
public class Article {
#PrimaryKey
#SerializedName("source")
#Expose
#ColumnInfo(name ="source")
#TypeConverters(SourceTypeConverter.class)
private Source source;
public Source getSource() {
return source;
}
public void setSource(Source source) {
this.source = source;
}
#SerializedName("author")
#Expose
#ColumnInfo(name = "author")
private String author;
#SerializedName("title")
#Expose
#ColumnInfo(name = "title")
private String title;
#SerializedName("description")
#Expose
#ColumnInfo(name = "description")
private String description;
#SerializedName("url")
#Expose
#ColumnInfo(name = "url")
private String url;
#SerializedName("urlToImage")
#Expose
#ColumnInfo(name = "urlToImage")
private String urlToImage;
#SerializedName("publishedAt")
#Expose
#ColumnInfo(name = "publishedAt")
private String publishedAt;
#SerializedName("content")
#Expose
#ColumnInfo(name = "content")
private String content;
public String getAuthor() {
return author;
}
public void setAuthor(String author) {
this.author = author;
}
public String getTitle() {
return title;
}
public void setTitle(String title) {
this.title = title;
}
public String getDescription() {
return description;
}
public void setDescription(String description) {
this.description = description;
}
public String getUrl() {
return url;
}
public void setUrl(String url) {
this.url = url;
}
public String getUrlToImage() {
return urlToImage;
}
public void setUrlToImage(String urlToImage) {
this.urlToImage = urlToImage;
}
public String getPublishedAt() {
return publishedAt;
}
public void setPublishedAt(String publishedAt) {
this.publishedAt = publishedAt;
}
public String getContent() {
return content;
}
public void setContent(String content) {
this.content = content;
}
}
below my SourceTypeConverter class
public class SourceTypeConverter {
#TypeConverter
public static Source ConvertSource(Source source){
return source == null ? null : new Source(source);
}
}
below Source.java
public class Source {
#SerializedName("id")
#Expose
private String id;
#SerializedName("name")
#Expose
private String name;
public Source(Source source) {
}
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
below I am getting C:\Users\Edgar\Desktop\Sport News\app\src\main\java\edgar\yodgorbek\sportnews\model\Article.java:18: error: Cannot figure out how to save this field into database. You can consider adding a type converter for it.
private Source source;
below my database class
#Database(entities = {Article.class}, version = 1, exportSchema = false)
public abstract class SportNewsDatabase extends RoomDatabase {
public abstract SportNewsDao sportNewsDao();
}
According to our chat in linkedin I could say that you are very ungrateful man. Your problem that room can't convert file type Source that you have in model. So you need to create converter from Source class to type that sqlite supported.
According to your latest published code I could say that you try to do something wrong. You have two tables: Source and Article. And you want to store link to Source inside Article.
Delete your type converter
Read this http://androidkt.com/database-relationships/
In short you need to create foreign key for Source in Article. This is one-to-one relation.

How to fix NumberFormatException when using gson.fromJson

I have an arraylist saved in shared preferences, of custom objects (Book) and now that I've updated the app (added a new property called Progress, which is an int), it seems that gson is trying to put one of the longs into this int variable.
This only happens to select users, who download the app through the store and I haven't been able to reproduce it. I posted something similar but without enough information here yesterday and realised I posted too early.
Note: at myrr.auto1.myreadingrecord1.sharedFunctions.loadArrayList(sharedFunctions.java:40) is the
bookList = gson.fromJson(json, type);
line
static ArrayList<Book> loadArrayList(Context context) {
ArrayList<Book> bookList;
SharedPreferences mPrefs = context.getSharedPreferences(PREF_NAME, Context.MODE_PRIVATE);
Gson gson = new Gson();
String json = mPrefs.getString("finishedBooks", "");
if (json.isEmpty()) {
bookList = new ArrayList<>();
} else {
Type type = new TypeToken<ArrayList<Book>>() {
}.getType();
bookList = gson.fromJson(json, type);
}
return bookList;
}
Fatal Exception: com.google.a.r: java.lang.NumberFormatException: Expected an int but was 1538513480946 at line 1 column 1891 path $[0].i
at com.google.gson.internal.bind.TypeAdapters$7.read(TypeAdapters.java:227)
at com.google.gson.internal.bind.TypeAdapters$7.read(TypeAdapters.java:217)
at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory$1.read(ReflectiveTypeAdapterFactory.java:129)
at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory$Adapter.read(ReflectiveTypeAdapterFactory.java:220)
at com.google.gson.internal.bind.TypeAdapterRuntimeTypeWrapper.read(TypeAdapterRuntimeTypeWrapper.java:41)
at com.google.gson.internal.bind.CollectionTypeAdapterFactory$Adapter.read(CollectionTypeAdapterFactory.java:82)
at com.google.gson.internal.bind.CollectionTypeAdapterFactory$Adapter.read(CollectionTypeAdapterFactory.java:61)
at com.google.gson.Gson.fromJson(Gson.java:888)
at com.google.gson.Gson.fromJson(Gson.java:853)
at com.google.gson.Gson.fromJson(Gson.java:802)
at myrr.auto1.myreadingrecord1.sharedFunctions.loadArrayList(sharedFunctions.java:40)
This is how the json string looks like, in old versions:
{"author":"Kerry Cohen Hoffmann",
"categories":"Juvenile Fiction",
"description":"Feeling neglected by her divorced parents and distant older sister, fourteen-year-old Jessica discovers how easily she is able to attract the attention of men and boys, without realizing the risks of her behavior.",
"endTime":1546742469961,
"imageURL":"http://books.google.com/books/content?id\u003d7wLjQH5_HjEC\u0026printsec\u003dfrontcover\u0026img\u003d1\u0026zoom\u003d5\u0026edge\u003dcurl\u0026source\u003dgbs_api",
"language":"en",
"moreInfoLink":"http://books.google.com/books?id\u003d7wLjQH5_HjEC\u0026dq\u003deasy\u0026hl\u003d\u0026as_pt\u003dBOOKS\u0026source\u003dgbs_api",
"pages":"176",
"startTime":1546553627662,
"title":"Easy"}
And this is the Book class properties, the setters and getters are pretty normal so i didnt include them.
public class Book implements Serializable{
private String author;
private String title;
private String pages;
private String imageURL;
private String description;
private String categories;
private String moreInfoLink;
private String language;
private int progress = 0;
private long startTime = 0L;
private long endTime = 0L;
public Book (String author, String title, String pages, String description, String imageURL, String categories, String moreInfoLink, String language) {
this.author = author;
this.title = title;
this.pages = pages;
this.description = description;
this.imageURL = imageURL;
this.categories = categories;
this.moreInfoLink = moreInfoLink;
this.language = language;
}
So for some, select users the fromJson tries to put the starttime or endtime value into the new progress property. How can I prevent this?
It should just create a new ArrayList of Book but it actually just crashes.
ADDING:
public void setEndTime(long endTime) {
this.endTime = endTime;
}
public void setStartTime(long startTime) {
this.startTime = startTime;}
theCRBook.setStartTime(Calendar.getInstance().getTimeInMillis());
As the error shows, you enabled the minifyEnabled in the build.gradle in order to obfuscate the code. In this case you need to do the #SerializedName("endTime"), #SerializedName("startTime") ... etc. for every variable you have in the model because the name of that variable will be changed on release versions.
public class Book implements Serializable {
#SerializedName("author")
private String author;
#SerializedName("title")
private String title;
#SerializedName("pages")
private String pages;
#SerializedName("imageURL")
private String imageURL;
#SerializedName("description")
private String description;
#SerializedName("categories")
private String categories;
#SerializedName("moreInfoLink")
private String moreInfoLink;
#SerializedName("language")
private String language;
#SerializedName("progress")
private int progress = 0;
#SerializedName("startTime")
private long startTime = 0L;
#SerializedName("endTime")
private long endTime = 0L;
public Book (String author, String title, String pages, String description, String imageURL, String categories, String moreInfoLink, String language) {
this.author = author;
this.title = title;
this.pages = pages;
this.description = description;
this.imageURL = imageURL;
this.categories = categories;
this.moreInfoLink = moreInfoLink;
this.language = language;
}
}
The exception states 1538513480946 is too large to fit into int, which is correct. It's a timestamp for 10/02/2018 # 8:51pm (UTC) and should be stored as long.
Perhaps you have an older version of Book class where startTime or endTime are declared as int and not long (or maybe just the setter parameter is int).
You can also use this class for your book class:
public class Book {
#SerializedName("author")
#Expose
private String author;
#SerializedName("categories")
#Expose
private String categories;
#SerializedName("description")
#Expose
private String description;
#SerializedName("endTime")
#Expose
private long endTime;
#SerializedName("imageURL")
#Expose
private String imageURL;
#SerializedName("language")
#Expose
private String language;
#SerializedName("moreInfoLink")
#Expose
private String moreInfoLink;
#SerializedName("pages")
#Expose
private String pages;
#SerializedName("startTime")
#Expose
private long startTime;
#SerializedName("title")
#Expose
private String title;
public String getAuthor() {
return author;
}
public void setAuthor(String author) {
this.author = author;
}
public String getCategories() {
return categories;
}
public void setCategories(String categories) {
this.categories = categories;
}
public String getDescription() {
return description;
}
public void setDescription(String description) {
this.description = description;
}
public long getEndTime() {
return endTime;
}
public void setEndTime(long endTime) {
this.endTime = endTime;
}
public String getImageURL() {
return imageURL;
}
public void setImageURL(String imageURL) {
this.imageURL = imageURL;
}
public String getLanguage() {
return language;
}
public void setLanguage(String language) {
this.language = language;
}
public String getMoreInfoLink() {
return moreInfoLink;
}
public void setMoreInfoLink(String moreInfoLink) {
this.moreInfoLink = moreInfoLink;
}
public String getPages() {
return pages;
}
public void setPages(String pages) {
this.pages = pages;
}
public long getStartTime() {
return startTime;
}
public void setStartTime(long startTime) {
this.startTime = startTime;
}
public String getTitle() {
return title;
}
public void setTitle(String title) {
this.title = title;
}
}
Just import gson in your book class:
import com.google.gson.annotations.Expose;
import com.google.gson.annotations.SerializedName;
After that, you can easily get some start/end time from your book array and convert it to date like this:
ArrayList<Book> books = loadArrayList(this);
Date date = new Date(books.get(0).getStartTime());
Log.i(TAG, "Date: " + date.toString());
You will get date from your json string:
Date: Thu Jan 03 17:13:47 EST 2019
Hope this can help you :)

retrofit 2.3.0 how to handle nested json?

I am kinda of new to retrofit and i am not sure how to handle a nested json structure like this. if any one can help how to parse this type of structure . i would really i appreciate it . i have been stuck for days
{
"status": "ok",
"totalResults": 20,
"articles": [
{
"source": {
"id": null,
"name": "Bradenton.com"
},
"author": "By EILEEN NG Associated Press",
"title": "Malaysia says search for missing plane to end in June",
"description": "An official says the search for Malaysia Airlines Flight 370 by a U.S. company will likely end in June, as families of passengers marked the fourth anniversary of the plane's disappearance with hope that the world's biggest aviation mystery will be solved.",
"url": "http://www.bradenton.com/news/business/article203286984.html",
"urlToImage": "http://www.mcclatchy-wires.com/incoming/ukogzw/picture203286949/alternates/LANDSCAPE_1140/Malaysia_Missing_Plane_57970.jpg",
"publishedAt": "2018-03-03T09:42:00Z"
}
]
}
the http://www.jsonschema2pojo.org/ to convert your json to POJO and use that for retrofit 2.3
If you don't know how many classes you need to make ,just copy and paste your json here click here.
This will help you and make your work easy.
Create some pojos:
class Source {
String id;
String name;
}
class Article{
Source source;
String author;
String title;
String description;
String url;
String urlToImage;
String publishedAt;
}
class GetArticlesResponse{
String status;
int totalResults;
List<Article> articles;
}
And then pass GetArticlesResponse to your retrofit call.
import retrofit2.Response;
import retrofit2.Call;
public interface YourInterface {
#GET("your_end_point")
Call<Response<GetArticlesResponse>> getArticles();
}
or if you're using RX:
import retrofit2.Response;
import rx.Observable;
public interface YourInterface {
#GET("your_end_point")
Observable<Response<GetArticlesResponse>> getArticles();
}
MainClass.java
public class MainClass {
#SerializedName("status")
#Expose
private String status;
#SerializedName("totalResults")
#Expose
private Integer totalResults;
#SerializedName("articles")
#Expose
private List<Article> articles = null;
public String getStatus() {
return status;
}
public void setStatus(String status) {
this.status = status;
}
public Integer getTotalResults() {
return totalResults;
}
public void setTotalResults(Integer totalResults) {
this.totalResults = totalResults;
}
public List<Article> getArticles() {
return articles;
}
public void setArticles(List<Article> articles) {
this.articles = articles;
}
}
Article.java
public class Article {
#SerializedName("source")
#Expose
private Source source;
#SerializedName("author")
#Expose
private String author;
#SerializedName("title")
#Expose
private String title;
#SerializedName("description")
#Expose
private String description;
#SerializedName("url")
#Expose
private String url;
#SerializedName("urlToImage")
#Expose
private String urlToImage;
#SerializedName("publishedAt")
#Expose
private String publishedAt;
public Source getSource() {
return source;
}
public void setSource(Source source) {
this.source = source;
}
public String getAuthor() {
return author;
}
public void setAuthor(String author) {
this.author = author;
}
public String getTitle() {
return title;
}
public void setTitle(String title) {
this.title = title;
}
public String getDescription() {
return description;
}
public void setDescription(String description) {
this.description = description;
}
public String getUrl() {
return url;
}
public void setUrl(String url) {
this.url = url;
}
public String getUrlToImage() {
return urlToImage;
}
public void setUrlToImage(String urlToImage) {
this.urlToImage = urlToImage;
}
public String getPublishedAt() {
return publishedAt;
}
public void setPublishedAt(String publishedAt) {
this.publishedAt = publishedAt;
}
}
Source.java
public class Source {
#SerializedName("id")
#Expose
private Object id;
#SerializedName("name")
#Expose
private String name;
public Object getId() {
return id;
}
public void setId(Object id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
Retrofit Interface
public interface YourInterface {
#GET("whatever api u are using")
Call<MainClass> getData(#Query("whatever key") String/int(whatever name)) //or leave blank
}
well when working with retrofit i suggest using Gson library with it which parses your json to an object type you should have created so first you should create an object representing your object from the response you get so it will be something like this in your case
public class Article implements Serializable {
private String author;
private String title;
private String description;
private String url;
private String urlToImage;
private String publishedAt;
private Source source;
public Story() {
}
public Story(String author,
String title,
Source source,
String description,
String url,
String urlToImage,
String publishedAt) {
this.author = author;
this.title = title;
this.source = source;
this.url = url;
this.urlToImage = urlToImage;
this.publishedAt = publishedAt;
}
public String getAuthor() {
return author;
}
public void setAuthor(String author) {
this.author = author;
}
public String getTitle() {
return title;
}
public void setTitle(String title) {
this.title = title;
}
public String getDescription() {
return description;
}
public void setDescription(String description) {
this.description = description;
}
public double getUrl() {
return url;
}
public void setUrl(String url) {
this.url = url;
}
public String getUrlToImage() {
return urlToImage;
}
public void setUrlToImage(String urlToImage) {
this.urlToImage = urlToImage;
}
public String getPublishedAt() {
return publishedAt;
}
public void setPublishedAt(String publishedAt) {
this.publishedAt = publishedAt;
}
public Source getSource() {
return source;
}
public void setSource(Source source) {
this.source = source;
}
}
and similarly create your other class which is the Source class containing your Source object
public class Source implements Serializable {
private id id;
private String name;
public Source() {
}
public Source(int id,
String name) {
this.id = id;
this.name = name;
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
now in your retrofit api code you could do something like this
#GET("YOUR_ENDPOINT/")
Call<JsonObject> getArticles(... put your required fields here example ...#Query("token") String token);
and in your activity do something like this
List mArticleList = new ArrayList<>();
String mTotalResults = "";
UserApi service = ServiceGenerator.createService(UserApi.class);
Call<JsonObject> result = service.getArticles(token);
result.enqueue(new Callback<JsonObject>() {
#Override
public void onResponse(Call<JsonObject> call, Response<JsonObject> response) {
if (response.code() == 200) {
mArticleList = null;
JsonArray data = response.body().getAsJsonObject("data").getAsJsonArray("articles");
mArticleList = new Gson().fromJson(data.toString(), new TypeToken<List<Article>>(){}.getType());
mTotalResults = response.body().getAsJsonObject("data").getAsString("totalResults");
//if you want it as an integer you could do something like
int totalResults = Integer.parseInt(mTotalResults);
//... do what you want with your list
//...
}
}
#Override
public void onFailure(Call<JsonObject> call, Throwable t) {
//do what you have to do in case of error
}
});
}
hope this helps

Duplicated attribute in Firebase

I have a model NewsFeedItem like this:
public class NewsFeedItem {
#PropertyName("like_number")
protected int likeCount = 0;
#PropertyName("time")
protected long timestamp;
#PropertyName("ownerUid")
protected String ownerUid;
#PropertyName("ownerUsername")
protected String ownerUsername;
#PropertyName("comments")
protected List<Comment> comments;
#PropertyName("likes")
protected Set<String> likes; //Store user uid of who like this status
public NewsFeedItem() {
}
protected NewsFeedItem(int likeCount, long timestamp, String ownerUid, String ownerUsername, List<Comment> comments, Set<String> likes) {
this.ownerUid = ownerUid;
this.ownerUsername = ownerUsername;
this.likeCount = likeCount;
this.timestamp = timestamp;
this.comments = comments;
this.likes = likes;
}
public int getLikeCount() {
return likeCount;
}
public void setLikeCount(int likeCount) {
this.likeCount = likeCount;
}
public long getTimestamp() {
return timestamp;
}
public void setTimestamp(long timestamp) {
this.timestamp = timestamp;
}
public String getOwnerUid() {
return ownerUid;
}
public void setOwnerUid(String ownerUid) {
this.ownerUid = ownerUid;
}
public String getOwnerUsername() {
return ownerUsername;
}
public void setOwnerUsername(String ownerUsername) {
this.ownerUsername = ownerUsername;
}
public List<Comment> getComments() {
return comments;
}
public void setComments(List<Comment> comments) {
this.comments = comments;
}
public Set<String> getLikes() {
return likes;
}
public void setLikes(Set<String> likes) {
this.likes = likes;
}
}
Then I subclass it in Status model:
#IgnoreExtraProperties
public class Status extends NewsFeedItem {
#PropertyName("content")
protected String content;
#PropertyName("photo")
protected String photoUrl;
public Status() {
//Required for deserialize
}
public Status(String ownerUid, String ownerUsername, String content, String photoUrl, int likeCount, long timestamp, List<Comment> comments, Set<String> likes) {
super(likeCount, timestamp, ownerUid, ownerUsername, comments, likes);
this.content = content;
this.photoUrl = photoUrl;
}
public String getContent() {
return content;
}
public void setContent(String content) {
this.content = content;
}
public String getPhotoUrl() {
return photoUrl;
}
public void setPhotoUrl(String photoUrl) {
this.photoUrl = photoUrl;
}
}
The code pushing data to Firebase:
#Override
public void pushStatusToFirebase(Status status) {
database.getReference("status").push().setValue(status);
}
But when I push to Firebase the like_number and likeCount display together like this:
It also happen to all of my model class. Please help me.
To solve this, you need to make all your fields public and not protected as they are now, otherwise the annotations will not work.
Now, the annotation takes into account both the field name as well as the getter/setter names to serialize. You have this problem because the fields as well as the getter/setters were getting serialized and that's why are resulting duplicates.
So use the annotation on the field name which are public and ignore the getter/setters. This will solve your problem. Your data will be properly serialized with the property name you want and there will be no duplicates as well.
Try to mark with #PropertyName your getters instead of fields. Another option that may be working - mark with #Exclude your getters.

Categories