dks551:
私は、JSON文字列を持っていると私はジャクソンライブラリを使用して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, int offset, int len, IOContext ctxt, boolean recyclable)
throws IOException {
return new MyParser(super._createParser(data, offset, len, 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
バージョン2.7.4のための更新されたコードを追加: -
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>
LppEdd:
編集:との間に微妙な違いがある2.7.*
とは2.9.*
。
一方で2.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;
}
}
出力: {"name":"xyz-3","price":90.09}
あなたのコードは罰金だ、それがテストされ、働いています;)