Android, a mistake at the date of the server
-
I'll get the data from the server:
Retrofit client = new Retrofit.Builder() .baseUrl(Constants.HOST) .addConverterFactory(GsonConverterFactory.create()) .build(); final UserApi service = client.create(UserApi.class); final Call<List<Room>> partRooms = service.getPartRooms(FROM_INT, TO_INT);
new Thread(new Runnable() { @Override public void run() { try { Log.e("samuliak", "Start execute"); Response<List<Room>> response = partRooms.execute(); allRooms = response.body(); Log.e("samuliak", "exute is finished. List size > "+allRooms.size()); } catch (IOException e) { e.printStackTrace(); } } }).start();
Subject model:
public class Room {
@SerializedName("roomID")
@Expose
private Integer roomID;
@SerializedName("name")
@Expose
private String name;
@SerializedName("password")
@Expose
private String password;
@SerializedName("creationDate")
@Expose
private Date creationDate;
@SerializedName("owner")
@Expose
private User owner;public Room() {}
public Room(Integer roomID, String name, String password, Date creationDate, User owner) {
this.roomID = roomID;
this.name = name;
this.password = password;
this.creationDate = creationDate;
this.owner = owner;
}public Integer getRoomID() {
return roomID;
}public void setRoomID(Integer roomID) {
this.roomID = roomID;
}public String getName() {
return name;
}public void setName(String name) {
this.name = name;
}public String getPassword() {
return password;
}public void setPassword(String password) {
this.password = password;
}public Date getCreationDate() {
return creationDate;
}public void setCreationDate(Date creationDate) {
this.creationDate = creationDate;
}public User getOwner() {
return owner;
}public void setOwner(User owner) {
this.owner = owner;
}
♪
Mistake:
07-04 07:29:09.348 9830-9956/com.project.samuliak.messenger E/AndroidRuntime: FATAL EXCEPTION: Thread-243
Process: com.project.samuliak.messenger, PID: 9830
com.google.gson.JsonSyntaxException: 1355263200000
at com.google.gson.internal.bind.DateTypeAdapter.deserializeToDate(DateTypeAdapter.java:74)
at com.google.gson.internal.bind.DateTypeAdapter.read(DateTypeAdapter.java:59)
at com.google.gson.internal.bind.DateTypeAdapter.read(DateTypeAdapter.java:41)
at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory$1.read(ReflectiveTypeAdapterFactory.java:116)
at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory$Adapter.read(ReflectiveTypeAdapterFactory.java:216)
at com.google.gson.internal.bind.TypeAdapterRuntimeTypeWrapper.read(TypeAdapterRuntimeTypeWrapper.java:40)
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 retrofit2.converter.gson.GsonResponseBodyConverter.convert(GsonResponseBodyConverter.java:37)
at retrofit2.converter.gson.GsonResponseBodyConverter.convert(GsonResponseBodyConverter.java:25)
at retrofit2.ServiceMethod.toResponse(ServiceMethod.java:116)
at retrofit2.OkHttpCall.parseResponse(OkHttpCall.java:211)
at retrofit2.OkHttpCall.execute(OkHttpCall.java:174)
at retrofit2.ExecutorCallAdapterFactory$ExecutorCallbackCall.execute(ExecutorCallAdapterFactory.java:89)
at com.project.samuliak.messenger.fragments.tab_fragments.Rooms$1.run(Rooms.java:77)
at java.lang.Thread.run(Thread.java:818)
Caused by: java.text.ParseException: Failed to parse date ["1355263200000']: Invalid time zone indicator '0' (at offset 0)
at com.google.gson.internal.bind.util.ISO8601Utils.parse(ISO8601Utils.java:274)
at com.google.gson.internal.bind.DateTypeAdapter.deserializeToDate(DateTypeAdapter.java:72)
at com.google.gson.internal.bind.DateTypeAdapter.read(DateTypeAdapter.java:59)
at com.google.gson.internal.bind.DateTypeAdapter.read(DateTypeAdapter.java:41)
at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory$1.read(ReflectiveTypeAdapterFactory.java:116)
at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory$Adapter.read(ReflectiveTypeAdapterFactory.java:216)
at com.google.gson.internal.bind.TypeAdapterRuntimeTypeWrapper.read(TypeAdapterRuntimeTypeWrapper.java:40)
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 retrofit2.converter.gson.GsonResponseBodyConverter.convert(GsonResponseBodyConverter.java:37)
at retrofit2.converter.gson.GsonResponseBodyConverter.convert(GsonResponseBodyConverter.java:25)
at retrofit2.ServiceMethod.toResponse(ServiceMethod.java:116)
at retrofit2.OkHttpCall.parseResponse(OkHttpCall.java:211)
at retrofit2.OkHttpCall.execute(OkHttpCall.java:174)
at retrofit2.ExecutorCallAdapterFactory$ExecutorCallbackCall.execute(ExecutorCallAdapterFactory.java:89)
at com.project.samuliak.messenger.fragments.tab_fragments.Rooms$1.run(Rooms.java:77)
at java.lang.Thread.run(Thread.java:818)
Caused by: java.lang.IndexOutOfBoundsException: Invalid time zone indicator '0'
How do you decide?
UPDATE
Problem solved, but there's a new one. Glass of error:
07-04 07:55:31.475 19841-19962/com.project.samuliak.messenger E/AndroidRuntime: FATAL EXCEPTION: Thread-267
Process: com.project.samuliak.messenger, PID: 19841
com.google.gson.JsonSyntaxException: java.lang.IllegalStateException: Expected BEGIN_ARRAY but was STRING at line 1 column 172 path $[0].owner.imageByteArray
at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory$Adapter.read(ReflectiveTypeAdapterFactory.java:220)
at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory$1.read(ReflectiveTypeAdapterFactory.java:116)
at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory$Adapter.read(ReflectiveTypeAdapterFactory.java:216)
at com.google.gson.internal.bind.TypeAdapterRuntimeTypeWrapper.read(TypeAdapterRuntimeTypeWrapper.java:40)
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 retrofit2.converter.gson.GsonResponseBodyConverter.convert(GsonResponseBodyConverter.java:37)
at retrofit2.converter.gson.GsonResponseBodyConverter.convert(GsonResponseBodyConverter.java:25)
at retrofit2.ServiceMethod.toResponse(ServiceMethod.java:116)
at retrofit2.OkHttpCall.parseResponse(OkHttpCall.java:211)
at retrofit2.OkHttpCall.execute(OkHttpCall.java:174)
at retrofit2.ExecutorCallAdapterFactory$ExecutorCallbackCall.execute(ExecutorCallAdapterFactory.java:89)
at com.project.samuliak.messenger.fragments.tab_fragments.Rooms$1$1.run(Rooms.java:95)
at java.lang.Thread.run(Thread.java:818)
Caused by: java.lang.IllegalStateException: Expected BEGIN_ARRAY but was STRING at line 1 column 172 path $[0].owner.imageByteArray
at com.google.gson.stream.JsonReader.beginArray(JsonReader.java:350)
at com.google.gson.internal.bind.ArrayTypeAdapter.read(ArrayTypeAdapter.java:70)
at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory$1.read(ReflectiveTypeAdapterFactory.java:116)
at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory$Adapter.read(ReflectiveTypeAdapterFactory.java:216)
at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory$1.read(ReflectiveTypeAdapterFactory.java:116)
at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory$Adapter.read(ReflectiveTypeAdapterFactory.java:216)
at com.google.gson.internal.bind.TypeAdapterRuntimeTypeWrapper.read(TypeAdapterRuntimeTypeWrapper.java:40)
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 retrofit2.converter.gson.GsonResponseBodyConverter.convert(GsonResponseBodyConverter.java:37)
at retrofit2.converter.gson.GsonResponseBodyConverter.convert(GsonResponseBodyConverter.java:25)
at retrofit2.ServiceMethod.toResponse(ServiceMethod.java:116)
at retrofit2.OkHttpCall.parseResponse(OkHttpCall.java:211)
at retrofit2.OkHttpCall.execute(OkHttpCall.java:174)
at retrofit2.ExecutorCallAdapterFactory$ExecutorCallbackCall.execute(ExecutorCallAdapterFactory.java:89)
at com.project.samuliak.messenger.fragments.tab_fragments.Rooms$1$1.run(Rooms.java:95)
at java.lang.Thread.run(Thread.java:818)
UPDATE #2
User:
public class User implements Parcelable {
@SerializedName("userID")
@Expose
private Integer userID;
@SerializedName("name")
@Expose
private String name;
@SerializedName("password")
@Expose
private String password;
@SerializedName("occupation")
@Expose
private String occupation;
@SerializedName("age")
@Expose
private Integer age;
@SerializedName("imageByteArray")
@Expose
private byte[] imageByteArray;public User() {}
public User(String name, String password, String occupation, Integer age) {
this.name = name;
this.password = password;
this.occupation = occupation;
this.age = age;
}public Integer getUserID() {
return userID;
}public void setUserID(Integer userID) {
this.userID = userID;
}public String getName() {
return name;
}public void setName(String name) {
this.name = name;
}public String getPassword() {
return password;
}public void setPassword(String password) {
this.password = password;
}public String getOccupation() {
return occupation;
}public void setOccupation(String occupation) {
this.occupation = occupation;
}public Integer getAge() {
return age;
}public void setAge(Integer age) {
this.age = age;
}public Bitmap getImage() {
return BitmapFactory.decodeByteArray(imageByteArray, 0, imageByteArray.length);
}public void setImage(Bitmap photo) {
ByteArrayOutputStream stream = new ByteArrayOutputStream();
photo.compress(Bitmap.CompressFormat.PNG, 100, stream);
imageByteArray = stream.toByteArray();
}/////////////////// Parcelable
protected User(Parcel in) {
name = in.readString();
password = in.readString();
occupation = in.readString();
imageByteArray = in.createByteArray();
}public static final Creator<User> CREATOR = new Creator<User>() {
@Override
public User createFromParcel(Parcel in) {
return new User(in);
}@Override public User[] newArray(int size) { return new User[size]; }
};
@Override
public int describeContents() {
return 0;
}@Override
public void writeToParcel(Parcel dest, int flags) {
dest.writeString(name);
dest.writeString(password);
dest.writeString(occupation);
dest.writeByteArray(imageByteArray);
}
♪
-
Gson can't recognize your format, help him:
GsonBuilder builder = new GsonBuilder(); builder.registerTypeAdapter(Date.class, new DateTypeAdapter()); builder.registerTypeAdapter(byte[].class, new ByteArrayAdapter()); Retrofit client = new Retrofit.Builder() .baseUrl(Constants.HOST) .addConverterFactory(GsonConverterFactory.create(builder.create())) .build();
public class DateTypeAdapter implements JsonDeserializer<Date>{
@Override
public Date deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context) throws JsonParseException {
return new Date(json.getAsLong());
}
}public class ByteArrayAdapter implements JsonDeserializer<byte[]> {
@Override
public byte[] deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context) throws JsonParseException {
return json.getAsString().getBytes();
}
}
I'm not sure if you'd better make your class-wrapper for byte. ♪ ♪