40

我有一个值未知的对象,比如说

{
 "data": [
    {"a":...,
    "dont_know_what_else_is_here":....}
 ]
}

我只想将“数据”的值作为字符串存储到变量/数据库中。

我应该如何从流 API 中读取它?

4

9 回答 9

57

假设您已经将该对象读入JsonNode,您可以这样做:

String content = jsonNode.get("data").textValue();

UPD:因为您使用的是流式解析器,所以这个关于 Jackson 用法的示例可能会有所帮助。

UPD:方法名称现在是 textValue() - docs

于 2013-02-05T08:22:07.843 回答
30

当我们尝试从 JsonNode 获取字符串形式的数据时,我们通常使用asText,但我们应该使用textValue代替。

asText:如果节点是值节点(方法 isValueNode() 返回 true),则返回容器值的有效字符串表示的方法,否则为空字符串。

textValue:用于访问字符串值的方法。不对非字符串值节点进行任何转换;对于非字符串值(isTextual() 返回 false 的值),将返回 null。对于字符串值,永远不会返回 null(但可能是空字符串)

那么我们举个例子,

JsonNode getJsonData(){
    ObjectMapper mapper = new ObjectMapper();
    ObjectNode node = mapper.createObjectNode(); 
    node.put("anyParameter",null);
    return node;
}
JsonNode node = getJsonData();
json.get("anyParameter").asText() // this will give output as "null"
json.get("").textValue() // this will give output as null
于 2016-10-19T14:26:00.323 回答
6

您可以根据键值对获取地图中的数据。

Map<String, Object> mp = mapper.readValue(new File("xyz.txt"),new TypeReference<Map<String, Object>>() {});

现在从地图中获取值:

mp.get("data");
于 2013-02-05T09:58:24.163 回答
4

假设您已经有一个解析器并且它指向“数据”令牌(例如来自自定义反序列化器),您可以执行以下操作:

ObjectMapper mapper = new ObjectMapper();
JsonNode treeNode = mapper.readTree(parser);
return treeNode.toString();

这将为您提供包含"data"值的字符串。

于 2017-03-30T14:11:01.117 回答
3

您可以为 JSON 结果设置一些实体类。

String json = "your_json";
ObjectMapper mapper = new ObjectMapper();
Entity entity = mapper .readValue(json, Entity.class);
// here you can do everything with entity as you wish

// to write Entity value as String when you wish
String text = mapper.writeValueAsString(object);
// to write Entity child's value as String when you wish (let's data contain data part)
String data = mapper.writeValueAsString(object.getData());
于 2013-02-05T08:59:21.747 回答
1

假设您有一个名为 User 的 POJO java 类(取自此

public class User {
public enum Gender { MALE, FEMALE };

public class Name {
    private String _first, _last;

    public String getFirst() { return _first; }
    public String getLast() { return _last; }

    public void setFirst(String s) { _first = s; }
    public void setLast(String s) { _last = s; }
}

private Gender _gender;
private Name _name;
private boolean _isVerified;
private byte[] _userImage;

public Name getName() { return _name; }
public boolean isVerified() { return _isVerified; }
public Gender getGender() { return _gender; }
public byte[] getUserImage() { return _userImage; }

public void setName(Name n) { _name = n; }
public void setVerified(boolean b) { _isVerified = b; }
public void setGender(Gender g) { _gender = g; }
public void setUserImage(byte[] b) { _userImage = b; }

}

所以现在你有来自任何地方的 JSON 字符串,比如 web socket 或其他地方。作为一个例子假设这是你得到的字符串

String json = "{\n" +
            "  \"name\" : { \"first\" : \"Joe\", \"last\" : \"Sixpack\" },\n" +
            "  \"gender\" : \"MALE\",\n" +
            "  \"verified\" : false,\n" +
            "  \"userImage\" : \"Rm9vYmFyIQ==\"\n" +
            "}";

现在您可以使用这段代码将这个 JSON 字符串转换为 POJO 对象。

ObjectMapper mapper = new ObjectMapper();
User user = mapper .readValue(json, User.class);
于 2015-11-03T06:15:28.333 回答
0

终于通过阅读教程页面找到了解决方案。

只是在这里给别人一个指针:

  1. 创建解析器时切换到使用 MappingJSONFactory:

        HttpResponse response = client.execute(request);
        JsonFactory jfactory = new MappingJsonFactory();
        JsonParser parser=jfactory.createJsonParser(response.getEntity().getContent());
    
  2. 然后你可以做

        parser.readValueAsTree().toString();
    

或根据需要解析它。

于 2013-02-05T15:18:15.150 回答
0

我假设您只想使用 Streaming API 从输入中读取子树——但最后,您需要将整个子树作为一件事存储在 DB(或变量)中。

因此,您可能想要使用的是JsonParser.readValueAs(MyType.class)- 这将调用ObjectMapper(并且要使其工作,必须通过JsonFactory访问创建解析器ObjectMapper;或者您需要调用JsonFactory.setCodec(mapper))。

如果内容是任意的,您可以将其读取为Mapor JsonNode

Map<String,Object> map = parser.readValueAs(Map.class);
// or
JsonNode root = parser.readValueAsTree();

只要JsonParser指向您要数据绑定的 JSON 对象的 START_ELEMENT。

于 2013-02-06T04:58:10.063 回答
0

如果使用String datain createParser(data),我使用此方法通过流 api 收集字符串内容:

if ("data".equals(fieldname))
     String strData = getValueAsString(jp);

    private static String getValueAsString(JsonParser jp)
        throws com.fasterxml.jackson.core.JsonParseException, IOException {
    JsonToken token = jp.getCurrentToken();
    int counter = 0;

    long startIndex = jp.getCurrentLocation().getCharOffset();
    long endIndex = 0;

    if (token == JsonToken.START_OBJECT) {
        // JsonLocation location = jp.getCurrentLocation();
        // startIndex = location.getCharOffset();
        // System.out.println(",location=" + new Gson().toJson(location) +
        // ", start=" + startIndex);

        counter++;
        while (counter > 0) {
            token = jp.nextToken();
            if (token == JsonToken.START_OBJECT)
                counter++;
            if (token == JsonToken.END_OBJECT) {
                counter--;
                endIndex = jp.getCurrentLocation().getCharOffset();
            }
        }

        return data.substring((int) startIndex - 1, (int) endIndex);

    } else if (token == JsonToken.START_ARRAY) {
        counter++;
        while (counter > 0) {
            token = jp.nextToken();
            if (token == JsonToken.START_ARRAY)
                counter++;
            if (token == JsonToken.END_ARRAY) {
                counter--;
                endIndex = jp.getCurrentLocation().getCharOffset();
            }
        }
        return data.substring((int) startIndex - 1, (int) endIndex);

    } else {
        return jp.getText();
    }
}

它在数据源为字符串时有效。对于无字符串源,例如文件,使用JsonLocation.getByteOffset()代替JsonLocation.getCharOffset()

于 2015-07-29T09:27:06.967 回答