Jackson自动将以数字开头的字符串视为整数

mwg9r5ms  于 4个月前  发布在  其他
关注(0)|答案(2)|浏览(52)

如果你做这样的测试

public static void main(String[] args) throws IOException {
    ObjectMapper mapper2 = new ObjectMapper();

    SimpleModule module = new SimpleModule();
    module.addDeserializer(TestClass.class, new TestClassDeserializer());
    mapper2.registerModule(module);

    TestClass testClass = mapper2.readValue("5 ttt", TestClass.class);

    System.out.println(testClass.field);
}

private static class TestClassDeserializer extends JsonDeserializer<TestClass> {
    @Override
    public TestClass deserialize(final JsonParser p, final DeserializationContext ctxt) throws IOException {
        TestClass param = new TestClass();
        param.field = p.getValueAsString();
        return param;
    }
}

public static class TestClass {
    public String field;

    public TestClass() {
    }

    public TestClass(final String field) {
        this.field = field;
    }
}

字符串
你会得到“5”的结果:
我不明白为什么Jackson认为“5 ttt”是一个整数,有可能禁用这种行为吗?
P.S.(感谢Diego Borba的想法,但不幸的是它也不起作用)
如果我为字段添加验证器,就像这样

public static class TestClass {
    @JsonDeserialize(using = TestClassDeserializerForInsideField.class)
    public String field;

    public TestClass() {
    }

    public TestClass(final String field) {
        this.field = field;
    }
}


并为字段添加验证器:

public class TestClassDeserializerForInsideField extends JsonDeserializer {
    @Override
    public Object deserialize(final JsonParser p, final DeserializationContext ctxt) throws IOException, JsonProcessingException {
        final String valueAsString = p.getValueAsString();
        return valueAsString;
    }
}


这将不起作用。我需要从一个字符串“5 ttt”中创建对象TestClass。所以,如果我删除模块(TestClassDeserializer),比Jackson不能理解如何解析输入字符串(在哪个对象中)并抛出一个异常MismatchedInputException: Cannot construct instance,但如果我添加两个验证器,(TestClassDeserializerTestClassDeserializerForInsideField):Jackson只使用了一个-第一个(TestClassDeserializer)。而field_parallelizer只是被jackson跳过了。
P.S.这里是我的查询谷歌从浏览器历史记录(为了更好的搜索)jackson convert any string to intjackson trim string to intJsonDeserializer trim symbols int text whitespace

c2e8gylq

c2e8gylq1#

试试这个方法:

TestClass testClass = mapper2.readValue("\"5 ttt\"", TestClass.class);

字符串
通过在输入字符串周围添加双引号,像这样:"5 ttt",您显式地向Jackson指示该值应被视为字符串

注意事项

如果你有任何字符串值,你想用引号括起来,那么你必须小心地使用writeValueAsString***。

public static void main(String[] args) throws JsonProcessingException {
    String value = "hello";

    value = wrap(value);

    assert "\"hello\"".equals(value);

    value = "\"hello test 2 with quotes\"";

    value = wrap(value);

    assert "\"hello test 2 with quotes\"".equals(value);
}

private static String wrap(final String value) throws JsonProcessingException {
    if (!isQuotedString(value)) {
        ObjectMapper mapper = new ObjectMapper();
        return mapper.writeValueAsString(value);
    }
    return value;
}

private static boolean isQuotedString(Object value) {
    if (value instanceof String) {
        String stringValue = (String) value;
        return stringValue.startsWith("\"") && stringValue.endsWith("\"");
    }
    return false;
}


如果你不检查字符串是否已经有引号,它会导致在旧的引号周围有额外的引号**,这是错误的!

8nuwlpux

8nuwlpux2#

在这里,你需要使用writeValueAsString方法转换给定的字符串,并将该字符串传递给readValue方法,如下所示:

产品代码:

public class Abc {
    public static void main(String[] args) throws IOException {
        ObjectMapper mapper2 = new ObjectMapper();
        String json = mapper2.writeValueAsString("5 ttt");
        TestClass testClass = mapper2.readValue(json, TestClass.class);
        System.out.println(testClass.field);
    }

    public static class TestClass {

        public String field;

        public TestClass(){}

        public TestClass(String field) {
            this.field = field;
        }
    }
}

字符串

输出:

5 ttt

  • 注意:* 如果我们使用参数化构造函数,我们需要显式添加默认构造函数。

相关问题