timoffei
timoffei

Reputation: 147

Jackson2 custom deserializer factory

I am porting jackson 1.6 code to jackson 2 and stumbled upon a deprecated code.

What i did in jackson 1.6 is:

CustomDeserializerFactory sf = new CustomDeserializerFactory();
mapper.setDeserializerProvider(new StdDeserializerProvider(sf));
sf.addSpecificMapping(BigDecimal.class, new BigDecimalDeserializer());
t = mapper.readValue(ts, X[].class);

Anyone knows how to do it in jackson 2?

Upvotes: 7

Views: 6098

Answers (4)

StaxMan
StaxMan

Reputation: 116620

In Jackson 2.0:

  1. Create a Module (usually SimpleModule)
  2. Register custom handlers with it.
  3. Call ObjectMapper.registerModule(module);.

This is available on Jackson 1.x as well (since 1.8 or so).

Upvotes: 1

ryber
ryber

Reputation: 4555

To add a factory--not just a deserializer--don't use SimpleModule. Create your own Module and within it create a Deserializers object that is added to the SetUpContext. The Deserializers object will have access to similar methods that the factory did where you can get extra type information about the deserializer needed.

It will look something like this (note that it doesn't need to be an inner class):

public class MyCustomCollectionModule extends Module {

@Override
public void setupModule(final SetupContext context) {
    context.addDeserializers(new MyCustomCollectionDeserializers());
}

private static class MyCustomCollectionDeserializers implements Deserializers {

    ... 

    @Override
    public JsonDeserializer<?> findCollectionDeserializer(final CollectionType type, final DeserializationConfig config, final BeanDescription beanDesc, final TypeDeserializer elementTypeDeserializer, final JsonDeserializer<?> elementDeserializer) throws JsonMappingException {

        if (MyCustomCollection.class.equals(type.getRawClass())) {
            return new MyCustomCollectionDeserializer(type);
        }
        return null;
    }

    ...
}
}

Upvotes: 3

deFreitas
deFreitas

Reputation: 4448

Exemplifying @StaxMan answer

Basically you need to create a module (SimpleModule), add a deserializer and register this module

final SimpleModule sm = new SimpleModule();
        sm.addDeserializer(Date.class, new JsonDeserializer<Date>(){

            @Override
            public Date deserialize(JsonParser p, DeserializationContext ctxt)
                    throws IOException {
                try {
                    System.out.println("from my custom deserializer!!!!!!");
                    return new SimpleDateFormat("yyyy-MM-dd").parse(p.getValueAsString());
                } catch (ParseException e) {
                    System.err.println("aw, it fails: " + e.getMessage());
                    throw new IOException(e.getMessage());
                }
            }
        });

        final CreationBean bean = JsonUtils.getMapper()
                .registerModule(sm)
//                .setDateFormat(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"))
                .readValue("{\"dateCreation\": \"1995-07-19\"}", CreationBean.class);

Here a fully example

import java.io.IOException;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;

import com.fasterxml.jackson.core.JsonParser;
import com.fasterxml.jackson.databind.DeserializationContext;
import com.fasterxml.jackson.databind.JsonDeserializer;
import com.fasterxml.jackson.databind.module.SimpleModule;

/**
 * @author elvis
 * @version $Revision: $<br/>
 *          $Id: $
 * @since 8/22/16 8:38 PM
 */
public class JackCustomDeserializer {

    public static void main(String[] args) throws IOException {

        final SimpleModule sm = new SimpleModule();
        sm.addDeserializer(Date.class, new JsonDeserializer<Date>(){

            @Override
            public Date deserialize(JsonParser p, DeserializationContext ctxt)
                    throws IOException {
                try {
                    System.out.println("from my custom deserializer!!!!!!");
                    return new SimpleDateFormat("yyyy-MM-dd").parse(p.getValueAsString());
                } catch (ParseException e) {
                    System.err.println("aw, it fails: " + e.getMessage());
                    throw new IOException(e.getMessage());
                }
            }
        });

        final CreationBean bean = JsonUtils.getMapper()
                .registerModule(sm)
//                .setDateFormat(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"))
                .readValue("{\"dateCreation\": \"1995-07-19\"}", CreationBean.class);

        System.out.println("parsed bean: " + bean.dateCreation);
    }

    static class CreationBean {
        public Date dateCreation;
    }

}

Upvotes: 0

java4africa
java4africa

Reputation: 212

Here is an example of registering a module (in this case Joda date handling) in Jackson 2.x:

    ClientConfig clientConfig = new DefaultClientConfig();

    ObjectMapper mapper = new ObjectMapper();
    mapper.registerModule(new JodaModule());
    mapper.disable(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS);

    JacksonJsonProvider provider = new JacksonJsonProvider();
    provider.configure(SerializationFeature.INDENT_OUTPUT, true);
    provider.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);

    provider.setMapper(mapper);
    clientConfig.getSingletons().add(provider);

    Client client = Client.create(clientConfig);

Upvotes: 0

Related Questions