我有一个值未知的对象,比如说
{
"data": [
{"a":...,
"dont_know_what_else_is_here":....}
]
}
我只想将“数据”的值作为字符串存储到变量/数据库中。
我应该如何从流 API 中读取它?
当我们尝试从 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
您可以根据键值对获取地图中的数据。
Map<String, Object> mp = mapper.readValue(new File("xyz.txt"),new TypeReference<Map<String, Object>>() {});
现在从地图中获取值:
mp.get("data");
假设您已经有一个解析器并且它指向“数据”令牌(例如来自自定义反序列化器),您可以执行以下操作:
ObjectMapper mapper = new ObjectMapper();
JsonNode treeNode = mapper.readTree(parser);
return treeNode.toString();
这将为您提供包含"data"值的字符串。
您可以为 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());
假设您有一个名为 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);
终于通过阅读教程页面找到了解决方案。
只是在这里给别人一个指针:
创建解析器时切换到使用 MappingJSONFactory:
HttpResponse response = client.execute(request);
JsonFactory jfactory = new MappingJsonFactory();
JsonParser parser=jfactory.createJsonParser(response.getEntity().getContent());
然后你可以做
parser.readValueAsTree().toString();
或根据需要解析它。
我假设您只想使用 Streaming API 从输入中读取子树——但最后,您需要将整个子树作为一件事存储在 DB(或变量)中。
因此,您可能想要使用的是JsonParser.readValueAs(MyType.class)
- 这将调用ObjectMapper
(并且要使其工作,必须通过JsonFactory
访问创建解析器ObjectMapper
;或者您需要调用JsonFactory.setCodec(mapper)
)。
如果内容是任意的,您可以将其读取为Map
or JsonNode
:
Map<String,Object> map = parser.readValueAs(Map.class);
// or
JsonNode root = parser.readValueAsTree();
只要JsonParser
指向您要数据绑定的 JSON 对象的 START_ELEMENT。
如果使用String data
in 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()