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

Add support for serializing boolean/Boolean as number (0 or 1) #1480

Closed
jwilmoth opened this issue Dec 20, 2016 · 6 comments
Closed

Add support for serializing boolean/Boolean as number (0 or 1) #1480

jwilmoth opened this issue Dec 20, 2016 · 6 comments
Milestone

Comments

@jwilmoth
Copy link

Converting some older data formats means serializing & deserializing Java's boolean fields into 1 and 0 numbers as well as "T" and "F" characters. This post (http://stackoverflow.com/questions/26827343/jackson-serialize-boolean-to-1-0-instead-of-true-false) describes a custom serializer, but I believe there's value in including a couple additional serializers with the library itself.

@cowtowncoder
Copy link
Member

Ok. To some degree this could perhaps be covered by supporting variants of @JsonFormat annotation (and matching defaulting for types via "config overrides"), property format. This could, for example, allow accepting various String values. But it gets tricky to support numbers and strings.

So it may make sense to add support for some values, but also define limits: it is not practical to support essentially unbounded set of variations.

Having said that, I think that deserialization of 0 and 1 (or, actually, 0 and non-0) is already supported, as well as String versions of "true" and "false". Serialization as a number is probably not yet supported but would be doable via use of @JsonFormat.

@jwilmoth
Copy link
Author

jwilmoth commented Jan 4, 2017

While I do see (v2.8.5) com.fasterxml.jackson.databind.deser.std.StdDeserializer._parseBoolean(JsonParser p, DeserializationContext ctxt) looks for a int in practice (see test case below), I get the following error:

com.fasterxml.jackson.databind.exc.InvalidFormatException: Can not deserialize value of type java.lang.Boolean from String "0": only "true" or "false" recognized

@Test
    public void shouldDeserialize1ToTrue() throws Exception {
        CsvMapper csvMapper = new CsvMapper();
        ObjectReader objectReader = csvMapper.readerWithTypedSchemaFor(Foo.class);
        Foo foo = objectReader.readValue("1,1");
        assertThat(foo.getObjectBoolean(), is(true));
        assertThat(foo.isPrimitiveBoolean(), is(true));
    }

There seems to be some overlap between @JsonFormat and @JsonDeserialize is the former the recommended path?

@cowtowncoder
Copy link
Member

@jwilmoth At this point boolean/Boolean type does not consider @JsonFormat for anything, so I was just suggesting ways things could be improved.

However, string values "0" and "1" should by default be coercible. So perhaps there is a codepath that is not doing proper checks?

One question on code snippet: what does class Foo look like?

@cowtowncoder
Copy link
Member

Oh. I spoke too soon -- no, only JSON numbers 0 and 1 are accepted, not String value. This is by design at this point.

I will have to think about how to proceed. I don't think adding aliases for default is the best way, and instead should somehow use @JsonFormat. But since there's need for two sets of values, things get bit tricky.

@cowtowncoder cowtowncoder changed the title Add support for boolean (de)serialization to int (1/0) and char ("T/F") Add support for serializing boolean/Boolean as number (0 or 1) Jan 7, 2017
@cowtowncoder
Copy link
Member

Ok: I think what I'll do is tackle serialization as 0/1 first, using @JsonFormat and Shape.NUMBER.
This should be relatively easy to do.

Question of alternate String representations is more difficult, and a new issue should be filed for that.

@jwilmoth
Copy link
Author

jwilmoth commented Jan 9, 2017

FWIW here's the definition of the Foo class:

import javax.inject.Inject;

public class Foo {
    private boolean primitiveBoolean;
    private Boolean objectBoolean;

    public Foo() {
    }

    @Inject
    public Foo(Boolean aBoolean, boolean primitiveBoolean) {
        this.objectBoolean = aBoolean;
        this.primitiveBoolean = primitiveBoolean;
    }

    public boolean isPrimitiveBoolean() {
        return primitiveBoolean;
    }

    public void setPrimitiveBoolean(boolean primitiveBoolean) {
        this.primitiveBoolean = primitiveBoolean;
    }

    public Boolean getObjectBoolean() {
        return objectBoolean;
    }

    public void setObjectBoolean(Boolean objectBoolean) {
        this.objectBoolean = objectBoolean;
    }
}

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