我有一个JSON字符串,我想在使用Jackson库构造JsonNode时更改值.
例如:-
input: {"name":"xyz","price":"90.00"}
output:{"name":"xyz-3","price":90.90}
我创建了自己的JsonFactory并通过了自己的解析器.但我只能更改键,而不能更改与键关联的值.
码:
private static ObjectMapper create() {
ObjectMapper objectMapper = new ObjectMapper(new JsonFactory() {
@Override
protected JsonParser _createParser(byte[] data,int offset,int len,IOContext ctxt) throws IOException {
return new MyParser(super._createParser(data,offset,len,ctxt));
}
@Override
protected JsonParser _createParser(InputStream in,IOContext ctxt) throws IOException {
return new MyParser(super._createParser(in,ctxt));
}
@Override
protected JsonParser _createParser(Reader r,IOContext ctxt) throws IOException {
return new MyParser(super._createParser(r,ctxt));
}
@Override
protected JsonParser _createParser(char[] data,IOContext ctxt,boolean recyclable)
throws IOException {
return new MyParser(super._createParser(data,ctxt,recyclable));
}
});
private static final class MyParser extends JsonParserDelegate {
private MyParser(JsonParser d) {
super(d);
}
@Override
public String getCurrentName() throws IOException,JsonParseException {
....
}
@Override
public String getText() throws IOException,JsonParseException {
...
}
@Override
public Object getCurrentValue() {
...
}
@Override
public String getValueAsString() throws IOException {
...
}
@Override
public String getValueAsString(String defaultValue) throws IOException {
...
}
}
下面是从字符串构造JsonNode的代码.
mapper.readTree(jsonStr);
在这种情况下,当调用readTree方法时,不会调用getCurrentValue或getValueAsString方法,因此在创建JsonNode本身时,我无法更改该值.
json字符串也可以不同.基本上我想从字符串构造一个JsonNode.因此,在这里绑定特定的架构/ bean不是一个好选择.
如何解决呢? TIA
static class MyParser extends JsonParserDelegate {
MyParser(final JsonParser delegate) {
super(delegate);
}
@Override
public String getText() throws IOException {
final String text = super.getText();
if ("name".equals(getCurrentName())) {
return text + "-3";
}
return text;
}
@Override
public JsonToken nextToken() throws IOException {
if ("price".equals(getCurrentName())) {
// Advance token anyway
super.nextToken();
return JsonToken.VALUE_NUMBER_FLOAT;
}
return super.nextToken();
}
@Override
public int getCurrentTokenId() {
try {
if ("price".equals(getCurrentName())) {
return JsonTokenId.ID_NUMBER_FLOAT;
}
} catch (final IOException e) {
//
}
return super.getCurrentTokenId();
}
@Override
public NumberType getNumberType() throws IOException {
if ("price".equals(getCurrentName())) {
return NumberType.FLOAT;
}
return super.getNumberType();
}
@Override
public float getFloatValue() throws IOException {
return Float.parseFloat(getValueAsString("0")) + 0.09F;
}
@Override
public double getDoubleValue() throws IOException {
return Double.parseDouble(getValueAsString("0")) + 0.09D;
}
}
pom.xml:-
<dependency>
<groupId>com.fasterxml.jackson.dataformat</groupId>
<artifactId>jackson-dataformat-yaml</artifactId>
<version>2.8.7</version>
<!--<scope>test</scope>-->
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.dataformat</groupId>
<artifactId>jackson-dataformat-xml</artifactId>
<version>2.8.7</version>
</dependency>
最佳答案
编辑:2.7.*和2.9.*之间有细微的差别.
2.9.*可以区分double和float
原文链接:https://www.f2er.com/java/532897.html2.9.*可以区分double和float
getDoubleValue()
getFloatValue()
而是2.7.*仅使用
getDoubleValue()
即使是ID_NUMBER_FLOAT令牌.
因此,您需要确定是否要保持回溯兼容性.
您也可以像在这里一样覆盖这两者.
这就是您自定义MyParser所需的一切
static class MyParser extends JsonParserDelegate {
MyParser(final JsonParser delegate) {
super(delegate);
}
@Override
public String getText() throws IOException {
final String text = super.getText();
if ("name".equals(getCurrentName())) {
return text + "-3";
}
return text;
}
@Override
public JsonToken nextToken() throws IOException {
if ("price".equals(getCurrentName())) {
// Advance token anyway
super.nextToken();
return JsonToken.VALUE_NUMBER_FLOAT;
}
return super.nextToken();
}
@Override
public int getCurrentTokenId() {
try {
if ("price".equals(getCurrentName())) {
return JsonTokenId.ID_NUMBER_FLOAT;
}
} catch (final IOException e) {
//
}
return super.getCurrentTokenId();
}
@Override
public NumberType getNumberType() throws IOException {
if ("price".equals(getCurrentName())) {
return NumberType.FLOAT;
}
return super.getNumberType();
}
@Override
public float getFloatValue() throws IOException {
return Float.parseFloat(getValueAsString("0")) + 0.09F;
}
@Override
public double getDoubleValue() throws IOException {
return Double.parseDouble(getValueAsString("0")) + 0.09D;
}
}
您的代码看起来不错,并且已经过测试并且可以正常工作;)