美好时光!
说,有一个json字符串:{id:'a', type:'b', category:'c'}
,业务逻辑是这样的,以构建一个类别对象,我需要知道类别名称('c')和类型('b') 。显然我需要为类别编写自定义反序列化器(@JsonDeserialize(using = CategoryCustomDeserializer.class)
),并且获取类别的名称很简单,但我无法弄清楚如何获取类型的值...我试过这个:jsonParser.getCodec().readTree(jsonParser)
,但会返回null
。
请建议正确的方法。
修改: 这是解串器:
public class CategoryNameDeserializer extends JsonDeserializer<Category> {
@Override
public Category deserialize(JsonParser jp, DeserializationContext ctxt) throws IOException, JsonProcessingException {
if (jp.getCurrentToken() != JsonToken.END_OBJECT) {
String categoryName = jp.getText();
String type = ?????? <------------------------ How to do it
return Service.getInstance().getCategory(categoryName, type);
}
return null;
}
}
答案 0 :(得分:0)
好吧,我找到了答案。这是一种解决方法,但它有效。可以使用以下方法重置解析器:
private JsonParser getResetParser(JsonParser jp) throws IOException {
JsonFactory factory = jp.getCodec().getFactory();
StringReader inputSource = (StringReader) jp.getInputSource();
inputSource.reset();
BufferedReader br = new BufferedReader(inputSource);
String source = br.readLine();
return factory.createJsonParser(source);
}
然后:
private String findTokenText(JsonParser jp, String fieldName) throws IOException {
JsonParser parser = getResetParser(jp);
while (true) {
parser.nextToken();
if (parser.hasCurrentToken()) {
switch (parser.getCurrentToken()) {
case END_ARRAY:
case END_OBJECT:
case NOT_AVAILABLE:
case START_ARRAY:
case START_OBJECT:
case VALUE_EMBEDDED_OBJECT:
case VALUE_FALSE:
case VALUE_NUMBER_FLOAT:
case VALUE_NUMBER_INT:
case VALUE_TRUE:
// do nothing
break;
case FIELD_NAME:
String currentName = parser.getCurrentName();
if (fieldName.equals(currentName)) {
parser.nextToken();
return parser.getText();
}
break;
}
} else {
return null;
}
}
我不理解的是为什么尽管在inputSource.reset();
方法中执行jp.getText()
代码findTokenText
(只是在调试模式下尝试过),但返回“C”,就好像读者没有重置。
任何人都可以解释一下,为什么会这样?
另一种变体是避免自定义并使用this帖子中的建议。