处理Jackson中糟糕的Json属性值

时间:2013-11-12 11:25:41

标签: java android parsing jackson

我在我的android项目中使用Jackson库

我有一个班级

@JsonIgnoreProperties(ignoreUnknown = true)
public class SomeResponse{

@JsonPropery("wiki")
Wiki wiki;
}
@JsonIgnoreProperties(ignoreUnknown = true)
public class Wiki{
@JsonProperty("title")
String title;
@JsonProperty("description")
String description;
}

解析代码

String resultFromServer = ....;
ObjectMapper mapper = new ObjectMapper();
        mapper.enable(
                Feature.ACCEPT_EMPTY_STRING_AS_NULL_OBJECT);

Wiki str= mapper.readValue(resultFromServer,Wiki.class);

现在这段代码工作正常 问题有时响应会像这样返回

{wiki:"\n          "}

有时候

{wiki:"\n"}

因此解析失败。我能做到这一点

 String resultFromServer = ....; 
if (resultFromServer != null && resultFromServer.contains("\"\\\\n\"")) {
            resultFromServer = resultFromServer.replaceAll("\"\\\\n\"", "\"\"");
        }

现在此代码处理此案例{wiki:"\n"} 但第二种情况是不可预测的,因为"\n

之后的空格数

有没有办法在属性值中将此错误处理为null对象???

3 个答案:

答案 0 :(得分:1)

您可以使用替换特定模式的正则表达式替换字符串

您可以详细查找here

答案 1 :(得分:1)

您使用的是哪个版本的杰克逊?我已经使用2.2.2版测试了我的解决方案。在此版本中,您可以将构造函数添加到接受Wiki参数的String类中。 您的POJO类应如下所示:

@JsonIgnoreProperties(ignoreUnknown = true)
class Wiki {

    public Wiki() {
    }

    public Wiki(String title) {
        this.title = title;
    }

    @JsonProperty("title")
    private String title;

    @JsonProperty("description")
    private String description;

    // getters, setters, toString
}

使用示例:

ObjectMapper mapper = new ObjectMapper();
mapper.enable(DeserializationFeature.ACCEPT_EMPTY_STRING_AS_NULL_OBJECT);

SomeResponse response = mapper.readValue(json, SomeResponse.class);
System.out.println(response);

如果您不想创建具有奇怪内容的对象,您还可以为Wiki类编写自定义反序列化器。

class WikiJsonDeserializer extends JsonDeserializer<Wiki> {

    @Override
    public Wiki deserialize(JsonParser jp, DeserializationContext ctxt) throws IOException, JsonProcessingException {
        JsonToken token = jp.getCurrentToken();
        if (JsonToken.VALUE_STRING == token) {
            return null;
        }

        return jp.readValueAs(Wiki.class);
    }
}

您可以这样指定反序列化器:

@JsonDeserialize(using = WikiJsonDeserializer.class)
@JsonProperty("wiki")
private Wiki wiki;

答案 2 :(得分:1)

String.replaceAll使用正则表达式,您可以轻松地使用它来匹配任意数量的空格:

resultFromServer.replaceAll("\"\\s*\\\\n\\s*\"", "\"\"");

\s是空间的标志)。此外,contains测试不是必需的,但如果你想保留它,你必须用正则表达式匹配替换它以测试空格。

使用自定义indexof方法

对字符串进行正则表达式匹配
/**
 * contains with regex
 * 
 * @param pattern
 * @param s
 * @return
 */
public static boolean contains(Pattern pattern, String s) {
    return indexOf(pattern, s) > -1;
}

/**
 * indexOf with regex

 * 
 * @param pattern
 * @param s
 * @return
 */
public static int indexOf(Pattern pattern, String s) {
    Matcher matcher = pattern.matcher(s);
    return matcher.find() ? matcher.start() : -1;
}