从.NET序列化字符串反序列化时,Android MalformedJsonException

时间:2017-03-24 12:13:33

标签: android gson

我正在尝试使用serialized String解析此Gson

{
//other variables
"MODIFIED_ON":"/Date(1490354840000)/",
"MARKET_APP_URL":"http://marketplac...",
//other variables
}

我只发布了这两行,因为那些是投掷错误的。

String来自使用C# webservice的{​​{1}}。

这是我的错误:

  

com.google.gson.JsonSyntaxException:com.google.gson.stream.MalformedJsonException:第1行第1行路径的预期值$

我的问题出在这一行,而另一行则是因为它包含了JsonConvert.SerializeObject(MyObject)+等字符。 \(,...

我尝试将日期替换为更简单的格式,但我甚至无法将)用于这些字符串..

如何在不出现类似问题的情况下反序列化此Split

这是我的代码,其中包含用于数据的自定义String

Serializer

1 个答案:

答案 0 :(得分:1)

您的代码存在一些问题。

首先,Pattern.quote旨在引用正则表达式。无论你要做什么,它都将包裹在\Q\E分别包裹在头部和尾部的带引号的字符串:

System.out.println(Pattern.quote("foo"));

变成:

\Qfoo\E

分隔引用的正则表达式。这会导致JSON解析器失败:由于这些正则表达式文字,您的JSON文档变得不可解析。只是不要在那里使用它:

  

第1行第1列路径$

的预期值

接下来,您无需创建JsonParser。它的目的是从给定的输入创建内存中的JSON树。因此,除了给定的输入之外,您将获得一个中间JSON树(JsonElement及其子类),它们无缘无故地消耗内存和一些性能。

第三,使用正则表达式提取文本并不是那么糟糕。我不确定与使用子串的字符串切片相比的真实性能,但至少它会给你更多的表达:

final class DateJsonDeserializer
        implements JsonDeserializer<Date> {

    // Can be a singleton, but exposing via a factory method and leaving the constructor private (let the caller not care on _how_ this is instantiated)
    private static final JsonDeserializer<Date> dateJsonDeserializer = new DateJsonDeserializer();

    // /\/Date\(\d+\)\// as if it were sed
    private static final Pattern datePattern = Pattern.compile("/Date\\((\\d+)\\)/");
    // Just cache your default date, note the L literal for longs, so no need to parseLong at all

    private DateJsonDeserializer() {
    }

    static JsonDeserializer<Date> getDateJsonDeserializer() {
        return dateJsonDeserializer;
    }

    @Override
    public Date deserialize(final JsonElement jsonElement, final Type type, final JsonDeserializationContext context)
            throws JsonParseException {
        final String dateLiteral = jsonElement.getAsString();
        final Matcher matcher = datePattern.matcher(dateLiteral);
        // Not a valid date literal? Better throw an exception or improve the parser somehow, but don't return 1900 if possible
        if ( !matcher.matches() ) {
            throw new JsonParseException("Cannot parse: " + dateLiteral);
        }
        return new Date(parseLong(matcher.group(1)));
    }

}

样本映射:

final class LoggedUser {

    @SerializedName("MODIFIED_ON")
    final Date modifiedOn = null;

    @SerializedName("MARKET_APP_URL")
    final URL marketAppUrl = null;

}
final Gson gson = new GsonBuilder()
        .registerTypeAdapter(Date.class, getDateJsonDeserializer())
        .create();
final LoggedUser loggedUser = gson.fromJson(JSON, LoggedUser.class);
System.out.println(loggedUser.modifiedOn);
System.out.println(loggedUser.marketAppUrl);

输出:

  

Fri Mar 24 13:27:20 EET 2017
  http://marketplac ......