杰克逊读取价值为字符串

时间:2013-02-05 08:19:16

标签: java json jackson

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

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

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

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

10 个答案:

答案 0 :(得分:37)

如果您已将此对象读入JsonNode,则可以这样做:

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

UPD:由于您正在使用流式传输解析器,因此有关Jackson使用的this示例可能有所帮助。

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

答案 1 :(得分:15)

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

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

textValue:用于访问String值的方法。不对非String值节点进行任何转换;对于非String值(其中isTextual()返回false)将返回null。对于String值,永远不会返回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

答案 2 :(得分:6)

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

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

现在从map获取值:

mp.get("data");

答案 3 :(得分:2)

您可以拥有一些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());

答案 4 :(得分:2)

假设您已经拥有解析器并且它指向&#34;数据&#34; 令牌(例如来自自定义解串器),您可以执行以下内容:

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

这将为您提供包含&#34;数据&#34; 的值的String。

答案 5 :(得分:0)

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

在这里给别人一个指针:

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

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

        parser.readValueAsTree().toString();
    
  3. 或者根据需要解析它。

答案 6 :(得分:0)

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

所以你可能想要使用的是JsonParser.readValueAs(MyType.class) - 这将调用ObjectMapper(并且要使其工作,必须通过从{{1}访问的JsonFactory创建解析器或者您需要致电ObjectMapper)。

如果内容是任意的,您可以将其视为JsonFactory.setCodec(mapper)Map

JsonNode

Map<String,Object> map = parser.readValueAs(Map.class); // or JsonNode root = parser.readValueAsTree(); 指向您想要数据绑定的JSON对象的START_ELEMENT。

答案 7 :(得分:0)

如果在String data中使用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();
    }
}

当数据源是String时它可以工作。对于没有字符串来源,例如文件,使用JsonLocation.getByteOffset()而不是JsonLocation.getCharOffset()

答案 8 :(得分:0)

假设您有一个名为User(Taken from this)的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);

答案 9 :(得分:0)

这应该有效:

public static void main(String[] args) throws IOException {
    String content = new String(Files.readAllBytes(Paths.get("duke.java")));
}

找到它here