【问题标题】:How to remove special characters from JSON stream, so that I can use gson API to convert JSON objects to JAVA objects?如何从 JSON 流中删除特殊字符,以便我可以使用 gson API 将 JSON 对象转换为 JAVA 对象?
【发布时间】:2014-06-19 16:10:37
【问题描述】:

我正在尝试使用 Google gson API 将 JSON 对象序列化为 java 对象。 我需要从此流中删除特殊字符以进行序列化。 我如何做到这一点?

这是我从请求中得到的 JSON 对象:

{"color":"北极白","imageUrl":"http://www.xyz.com/images/z/1/7/8/8/2/1/1788212-p-DETAILED。 jpg","styleId":"1788212","originalPrice":"$64.95","price":"$64.95","productUrl":"http://www.xyz.com/product/7515478/color/51609" ,"percentOff":"0%"}

但是,当我尝试使用 Google 的 gson API 将其反序列化为 JAVA 对象时,它需要没有任何特殊字符的 JSON 对象,因此在遇到“$”和“%”时会引发异常。如何在不影响 json 对象的其余部分(即作为字符串获得的 json 结果)的情况下摆脱这些字符。

【问题讨论】:

  • 分享一些示例输入和预期输出以使其更清晰。
  • 嗨@Braj 我已经用示例输入编辑了我的帖子。
  • 是否要从 JSON 字符串中完全删除这些特殊字符?

标签: json gson


【解决方案1】:

它按预期完美运行。无需从 JSON 流中删除这些特殊字符即可将其转换为 Java 对象。

请看下面的示例代码:

BufferedReader reader = new BufferedReader(new FileReader(new File("json.txt")));
MyJSONObject data = new Gson().fromJson(reader, MyJSONObject.class);
System.out.println(new GsonBuilder().setPrettyPrinting().create().toJson(data));

class MyJSONObject {
    private String color;
    private String imageUrl;
    private String styleId;
    private String originalPrice;
    private String price;
    private String productUrl;
    private String percentOff;
    // getter & setter
}

输出:(由于 StackOverflow 站点的限制,我从输出中删除了 URL)

{
  "color": "Arctic White",
  "styleId": "1788212",
  "originalPrice": "$64.95",
  "price": "$64.95",
  "percentOff": "0%"
}

您可以根据需要尝试使用JsonDeserializer 对其进行反序列化。

我已经在上面发布了一个示例代码。找到它HERE


编辑

这里是使用JsonDeserializer的示例代码。

示例代码:

BufferedReader reader = new BufferedReader(new FileReader(new File("resources/json29.txt")));

class MyJSONObject {
    private String color;
    private String imageUrl;
    private String styleId;
    private double originalPrice;
    private double price;
    private String productUrl;
    private double percentOff;
    // getter & setter
}

class MyJSONObjectDeserializer implements JsonDeserializer<MyJSONObject> {

    @Override
    public MyJSONObject deserialize(final JsonElement json, final Type typeOfT,
            final JsonDeserializationContext context) throws JsonParseException {

        JsonObject jsonObject = json.getAsJsonObject();

        MyJSONObject myJSONObject = new MyJSONObject();
        myJSONObject.setColor(jsonObject.get("color").getAsString());
        myJSONObject.setImageUrl(jsonObject.get("imageUrl").getAsString());
        myJSONObject.setStyleId(jsonObject.get("styleId").getAsString());
        myJSONObject.setProductUrl(jsonObject.get("productUrl").getAsString());

        try {
            String price = jsonObject.get("price").getAsString();
            String originalPrice = jsonObject.get("originalPrice").getAsString();
            String percentOff = jsonObject.get("percentOff").getAsString();

            myJSONObject.setPrice(Double.valueOf(price.substring(1)));
            myJSONObject.setOriginalPrice(Double.valueOf(originalPrice.substring(1)));
            myJSONObject.setPercentOff(Double.valueOf(percentOff.substring(0,
                    percentOff.length() - 1)));

        } catch (NumberFormatException e) {
            e.printStackTrace();
        }

        return myJSONObject;
    }
}

MyJSONObject data = new GsonBuilder()
        .registerTypeAdapter(MyJSONObject.class, new MyJSONObjectDeserializer()).create()
        .fromJson(reader, MyJSONObject.class);

System.out.println(new GsonBuilder().setPrettyPrinting().create().toJson(data));

【讨论】:

  • Braj 如果我们将 price、originalPrice 和 percentoff 分别设为 Integer、Double 和 Double 格式,您的解决方案将不起作用。我需要上述格式,以便对输入数据进行算术运算。
  • 你能改变你的 JSON 字符串吗?数字周围有双引号。或者您可以尝试使用我的帖子中提到的JsonDeserializer,根据需要将字符串转换为数字。请看我在JsonDeserializer@ 的帖子中提到的示例
  • 我已根据您的需要编辑了我的帖子。看看吧。
【解决方案2】:

最简单的方法是将流转换为字符串,使用正则表达式或其他东西替换不需要的字符,然后调用 gson 将更正后的字符串转换为所需的 Java 对象。

【讨论】:

    【解决方案3】:

    据我了解,您的对象的 JSON 表示形式包含一个值,例如“0%”(从 JSON 的角度来看,这正式是一个字符串)。这当然是有效的 JSON,GSON 应该接受它……如果您将它反序列化为旨在包含字符串的东西。

    我的猜测是您实际上希望将“0”反序列化为数字类型。在这种情况下,你不能依靠 GSON 自动完成你想做的事情,你需要写一个custom deserializer

    上面链接中的示例显示了如何为 DateTime 对象执行此操作:

    private class DateTimeDeserializer implements JsonDeserializer<DateTime> {
      public DateTime deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context)
          throws JsonParseException {
        return new DateTime(json.getAsJsonPrimitive().getAsString());
      }
    }
    

    在您的情况下,您仍然需要执行 getAsString(),但不是将其传递给 DateTime 构造函数,而是希望应用您自己的转换(剥离“%”,解析数字部分等)并返回与您的对象对应的适当数据类型。

    【讨论】:

      猜你喜欢
      • 2013-05-19
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-10-17
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多