2

I have created a Jackson Custom Deserializer to deserialize a JSON string :

public class TestMapper extends StdDeserializer<Test> {

    public TestMapper() {
        this(null);
    }

    public TestMapper(Class<?> vc) {
        super(vc);
    }

    @Override
    public Test deserialize(JsonParser jsonParser, DeserializationContext deserializationContext) throws IOException {

I want to pass a "String argument" to the deserialize method that I want to use during deserialization. Is there a way to do that?

I'm calling the deserializer as follows in my code:

new ObjectMapper().readValue(json, Test.class)

and the Test Class is :

@JsonDeserialize(using = TestMapper.class)
public class Test {
5
  • you can pass any argument in the constructor Commented Mar 6, 2019 at 17:07
  • @SharonBenAsher -- I'm calling the desealizer as follow - new ObjectMapper().readValue(json, Test.class) and the Test Class has the @JsonDeserialize(using = TestMapper.class) annotataion. How can I pass the value in new ObjectMapper().readValue(json, Test.class) using constructor ? Commented Mar 6, 2019 at 17:17
  • you can register a deserializer programatically. see answer to this stackoverflow.com/questions/6553051/… Commented Mar 6, 2019 at 17:39
  • If I add the constructor public TestMapper(String test) { }, I get the message there is no default constructor available for the superclass. Commented Mar 6, 2019 at 18:39
  • @SharonBenAsher, adding public TestMapper(String test) {super(Test.class);this. test = test;} worked. Thanks for the help! Commented Mar 6, 2019 at 19:38

1 Answer 1

4

You need to create constructor which takes your extra argument which will be used during deserialisation:

import com.fasterxml.jackson.core.JsonParser;
import com.fasterxml.jackson.databind.DeserializationContext;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.deser.std.StdDeserializer;
import com.fasterxml.jackson.databind.module.SimpleModule;

import java.io.IOException;

public class JsonApp {

    public static void main(String[] args) throws Exception {
        SimpleModule customModule = new SimpleModule();
        customModule.addDeserializer(Test.class, new TestMapper("Extra value!!!"));

        ObjectMapper mapper = new ObjectMapper();
        mapper.registerModule(customModule);

        Test test = new Test();
        test.setValue("Value");

        String json = mapper.writeValueAsString(test);
        System.out.println(json);
        System.out.println(mapper.readValue(json, Test.class));
    }
}

class TestMapper extends StdDeserializer<Test> {

    private String extraConfig;

    public TestMapper() {
        this(null);
    }

    public TestMapper(String extraConfig) {
        super(Test.class);
        this.extraConfig = extraConfig;
    }

    @Override
    public Test deserialize(JsonParser jsonParser, DeserializationContext deserializationContext) throws IOException {
        Test test = new Test();
        test.setValue(extraConfig);

        return test;
    }
}

class Test {

    private String value;

    public String getValue() {
        return value;
    }

    public void setValue(String value) {
        this.value = value;
    }

    @Override
    public String toString() {
        return "Test{" +
                "value='" + value + '\'' +
                '}';
    }
}

Above code prints:

{"value":"Value"}
Test{value='Extra value!!!'}

You should always provide to super constructor your POJO class, for example, Test.class. If you need more complex initialisation, take a look on ContextualDeserializer.

Also, take a look:

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.