“Ngày không thể phân tích cú pháp: 1302828677828” đang cố gắng giải mã hóa bằng Gson một ngày định dạng mili giây nhận được từ máy chủ


80

Sau 4 giờ không ngừng cố gắng giải quyết vấn đề, tôi đã quyết định hỏi ở đây nếu ai đó có thể giúp tôi.

Vấn đề là ứng dụng khách Android của tôi khi cố gắng giải mã dữ liệu nhận được từ máy chủ đã ném ngoại lệ "Không thể phân tích: 1302828677828".

Tôi muốn biết liệu có thể giải mã ngày ở định dạng mili giây bằng Gson hay không.


Ngày / giờ này đại diện cho ngày / giờ nào?
Squonk

Bạn không thể chỉ phân tích cú pháp nó thành a longvà sau đó chuyển đổi theo chương trình longthành a Datetrong mã của bạn?
aroth

11
Cuối cùng tôi đã có giải pháp: // Tạo đối tượng json sẽ quản lý thông tin nhận được GsonBuilder builder = new GsonBuilder (); // Đăng ký bộ điều hợp để quản lý các loại ngày tháng như giá trị dài builder.registerTypeAdapter (Date.class, new JsonDeserializer <Date> () {public Date deserialize (JsonElement json, Type typeOfT, JsonDeserializationContext context) ném JsonParseException {return new Date (json .getAsJsonPrimitive (). getAsLong ());}}); Gson gson = builder.create ();
Alfonso

Câu trả lời:


147

Bình luận của Alfonso:

Cuối cùng tôi đã có giải pháp:

// Creates the json object which will manage the information received 
GsonBuilder builder = new GsonBuilder(); 

// Register an adapter to manage the date types as long values 
builder.registerTypeAdapter(Date.class, new JsonDeserializer<Date>() { 
   public Date deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context) throws JsonParseException {
      return new Date(json.getAsJsonPrimitive().getAsLong()); 
   } 
});

Gson gson = builder.create();

Cảm ơn bạn rất nhiều bạn đã tiết kiệm thời gian của tôi !!
Chris Sim

vấn đề về múi giờ
ChRoNoN 27/09/2016

Cảm ơn điều này đã giúp tôi. Mặc dù tôi đã sử dụng cái này cho Dấu thời gian.
Feru

này đang làm việc cho mỗi ngày được thông qua vào millisenconds, không cho đi qua một quy tắc cho tất cả các loại của các đối tượng phân tích cú pháp
Nather Webber

2
.getAsJsonPrimitive()có thể được bỏ qua, và với Java 8 lambdas nó thậm chí còn ngắn hơn:Gson gson = new GsonBuilder().registerTypeAdapter(Date.class, (JsonDeserializer) (json, typeOfT, context) -> new Date(json.getAsLong())).create();
gmk57

2

Tôi đã viết một ImprovedDateTypeAdapter dựa trên GSON DateTypeAdapter mặc định rằng ngày hỗ trợ mặc định định dạng dấu thời gian (dài) định dạng.

import com.google.gson.Gson;
import com.google.gson.JsonSyntaxException;
import com.google.gson.TypeAdapter;
import com.google.gson.TypeAdapterFactory;
import com.google.gson.reflect.TypeToken;
import com.google.gson.stream.JsonReader;
import com.google.gson.stream.JsonToken;
import com.google.gson.stream.JsonWriter;

import java.io.IOException;
import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Locale;
import java.util.TimeZone;

public final class ImprovedDateTypeAdapter extends TypeAdapter<Date> {

    public static final TypeAdapterFactory FACTORY = new TypeAdapterFactory() {

        public <T> TypeAdapter<T> create(Gson gson, TypeToken<T> typeToken) {

            @SuppressWarnings("unchecked")
            TypeAdapter<T> typeAdapter = (TypeAdapter<T>) ((typeToken.getRawType() == Date.class) ? new ImprovedDateTypeAdapter()
                    : null);
            return typeAdapter;
        }
    };
    private final DateFormat enUsFormat;
    private final DateFormat localFormat;
    private final DateFormat iso8601Format;

    public ImprovedDateTypeAdapter() {
        this.enUsFormat = DateFormat.getDateTimeInstance(2, 2, Locale.US);

        this.localFormat = DateFormat.getDateTimeInstance(2, 2);

        this.iso8601Format = buildIso8601Format();
    }

    private static DateFormat buildIso8601Format() {
        DateFormat iso8601Format = new SimpleDateFormat(
                "yyyy-MM-dd'T'HH:mm:ss'Z'", Locale.US);
        iso8601Format.setTimeZone(TimeZone.getTimeZone("UTC"));
        return iso8601Format;
    }

    public Date read(JsonReader in) throws IOException {
        if (in.peek() == JsonToken.NULL) {
            in.nextNull();
            return null;
        }
        return deserializeToDate(in.nextString());
    }

    private synchronized Date deserializeToDate(String json) {
        try {

            return new Date(Long.parseLong(json));
        } catch (Exception e) {

            try {

                return this.localFormat.parse(json);
            } catch (ParseException e1) {

                try {

                    return this.enUsFormat.parse(json);
                } catch (ParseException e2) {

                    try {

                        return this.iso8601Format.parse(json);
                    } catch (ParseException e3) {

                        throw new JsonSyntaxException(json, e3);
                    }
                }
            }
        }
    }

    public synchronized void write(JsonWriter out, Date value)
            throws IOException {
        if (value == null) {
            out.nullValue();
            return;
        }
        String dateFormatAsString = this.enUsFormat.format(value);
        out.value(dateFormatAsString);
    }
}

Để dùng nó:

// Creates the json object which will manage the information received 
GsonBuilder builder = new GsonBuilder(); 

// Register an adapter to manage the date types as long values 
builder.registerTypeAdapter(Date.class, new ImprovedDateTypeAdapter());

Gson gson = builder.create();

2
JsonSerializer<Date> serializer= new JsonSerializer<Date>() {
  @Override
  public JsonElement serialize(Date src, Type typeOfSrc, JsonSerializationContext 
             context) {
    return src == null ? null : new JsonPrimitive(src.getTime());
  }
};

JsonDeserializer<Date> deserializer= new JsonDeserializer<Date>() {
  @Override
  public Date deserialize(JsonElement json, Type typeOfT,
       JsonDeserializationContext context) throws JsonParseException {
    return json == null ? null : new Date(json.getAsLong());
  }
};

Gson gson = new GsonBuilder()
   .registerTypeAdapter(Date.class, serializer)
   .registerTypeAdapter(Date.class, deserializer).create();

1

Sử dụng đoạn mã dưới đây để chuyển đổi mili giây thành Ngày tháng trong khi xử lý JSON.

    GsonBuilder gsonBuilder = new GsonBuilder();
    // Adapter to convert long values to date types
    gsonBuilder.registerTypeAdapter(Date.class, new JsonDeserializer<Date>() {
        public Date deserialize(JsonElement jsonElement, Type typeOfObj, JsonDeserializationContext context)
               throws JsonParseException {
                   //Converting milliseconds to current Date. (instead of 1970)
                return new Date(jsonElement.getAsLong() * 1000);
            }
        });
    Gson gson = gsonBuilder.setPrettyPrinting().create();

0

Tôi gặp sự cố tương tự khi cố gắng giải mã hóa trường DateTime bằng ứng dụng khách Rest của thư viện chú thích Android . Như một giải pháp, tôi đã tạo GsonHttpMessageConverter tùy chỉnh

public class CustomGsonHttpMessageConverter extends GsonHttpMessageConverter {

    public CustomGsonHttpMessageConverter() {
        // Creates the json object which will manage the information received
        GsonBuilder builder = new GsonBuilder();

        // Register an adapter to manage the date types as long values
        builder.registerTypeAdapter(Date.class, new JsonDeserializer<Date>() {
            public Date deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context) throws JsonParseException {
                return new Date(json.getAsJsonPrimitive().getAsLong());
            }
        });

        setGson(builder.create());
    }
}

và xác định nó trong ứng dụng khách còn lại

@Rest(rootUrl = "http://192.168.1.1:8080", converters = {CustomGsonHttpMessageConverter.class})
public interface RestClient extends RestClientErrorHandling {
...

Tôi hy vọng nó sẽ hữu ích


0

Vì một số lý do, tôi đã gặp lỗi biên dịch trong Intellij với mã trên bằng cách sử dụng một lớp ẩn danh; một lambda đã làm việc cho tôi:

private static Gson buildGson(){
    // Deserialize longs as Dates
    final JsonDeserializer<Date> dateDeserializer = (json, type, context) -> json == null ? null : new Date(json.getAsLong());
    return new GsonBuilder().registerTypeAdapter(Date.class, dateDeserializer).create();
}
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.