Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

JsonParser from MismatchedInputException cannot getText() for floating-point value #2770

Closed
joca-bt opened this issue Jun 17, 2020 · 5 comments
Milestone

Comments

@joca-bt
Copy link

joca-bt commented Jun 17, 2020

I've stumbled upon another situation in which I'm not able to get the textual representation of the current token.

I have the following class:

public class Test {
    public Boolean value;
    public Boolean getValue() { return value; }
    public void setValue(Boolean value) { this.value = value; }
}

And the following object mapper:

ObjectMapper objectMapper = new ObjectMapper();
objectMapper.disable(MapperFeature.ALLOW_COERCION_OF_SCALARS);

I'm trying to deserialize something that would result in a MismatchedInputException: I'm providing a number to something that expects a boolean:

try {
    objectMapper.readValue("{ \"value\": 1.0 }", Test.class);
} catch (MismatchedInputException exception) {
    JsonParser parser = (JsonParser) exception.getProcessor();
    System.out.println(parser.currentToken());
    System.out.println(parser.getText());
} catch (Exception exception) {}

This results in:

VALUE_NUMBER_FLOAT

while I would expect parser.getText() to return "1.0".

Related with #2635. However that one was specifically for InputStreams, where here it happens for both Strings and InputStreams.

(Jackson 2.11.0)

@cowtowncoder
Copy link
Member

One quick question: have you observed this with other types? I guess I can test with int and long too, for example

@joca-bt
Copy link
Author

joca-bt commented Jun 17, 2020

I have, I can update it tomorrow when I'm back to work.

@cowtowncoder cowtowncoder changed the title JsonParser from MismatchedInputException cannot getText() JsonParser from MismatchedInputException cannot getText() for floating-point value Jun 18, 2020
@cowtowncoder cowtowncoder modified the milestones: 2.10.0, 2.11.1 Jun 18, 2020
@cowtowncoder
Copy link
Member

Fixed for 2.11.1.

@joca-bt
Copy link
Author

joca-bt commented Jun 19, 2020

Sorry for the late reply. Looks like it is only float for booleans.

import com.fasterxml.jackson.annotation.JsonSetter;
import com.fasterxml.jackson.annotation.Nulls;
import com.fasterxml.jackson.core.JsonParser;
import com.fasterxml.jackson.databind.MapperFeature;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.exc.MismatchedInputException;
import org.junit.jupiter.api.Test;

public class TestTest {
    @Test
    public void test() {
        readValue("{ \"value\": null }");
        readValue("{ \"value\": 1 }");
        readValue("{ \"value\": 1.0 }");
        readValue("{ \"value\": \"true\" }");
        readValue("{ \"value\": [] }");
        readValue("{ \"value\": {} }");
    }

    private void readValue(String value) {
        try {
            try {
                ObjectMapper objectMapper = new ObjectMapper();
                objectMapper.disable(MapperFeature.ALLOW_COERCION_OF_SCALARS)
                    .setDefaultSetterInfo(JsonSetter.Value.construct(Nulls.FAIL, Nulls.FAIL));
                objectMapper.readValue(value, Data.class);
            } catch (MismatchedInputException exception) {
                JsonParser parser = (JsonParser) exception.getProcessor();
                System.out.println(parser.currentToken());
                System.out.println(parser.getText());
            }
        } catch (Exception exception) {}
    }

    public static class Data {
        public Boolean value;
        public Boolean getValue() { return value; }
        public void setValue(Boolean value) { this.value = value; }
    }
}

@cowtowncoder
Copy link
Member

Thanks, makes sense. Code refactoring for 2.12 had actually resolved that for 2.12 branch, but I fixed it for 2.11.
The general problem is tricky, however: there is no real cure for the fact that parser will get closed, buffers recycled. One thing that could help would be use of DeserializationProblemHandler, as that will get called before exception is throw, before parser gets called.
Until then I can fix specific cases to force calling of parser.getText() before exception is thrown as that (and only that) will ensure that String for getText() is aggregated, retained, even if buffers will not be accessible any more.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants