Tuesday, July 14, 2015

Jackson Miscs



http://stackoverflow.com/questions/6526911/best-way-to-compare-2-json-files-in-java
This only addresses equality, not differences.
ObjectMapper mapper = new ObjectMapper();

JsonNode tree1 = mapper.readTree(jsonInput1);
JsonNode tree2 = mapper.readTree(jsonInput2);

boolean areTheyEqual = tree1.equals(tree2);
http://www.baeldung.com/jackson-bidirectional-relationships-and-infinite-recursion
The “User” entity:
1
2
3
4
5
public class User {
    public int id;
    public String name;
    public List<Item> userItems;
}
The “Item” entity:
1
2
3
4
5
public class Item {
    public int id;
    public String itemName;
    public User owner;
}
When we try to serialize an instance of “Item“, Jackson will throw a JsonMappingException exception:

com.fasterxml.jackson.databind.JsonMappingException:
Infinite recursion (StackOverflowError)
(through reference chain:
org.baeldung.jackson.bidirection.Item["owner"]
->org.baeldung.jackson.bidirection.User["userItems"]
->java.util.ArrayList[0]
->org.baeldung.jackson.bidirection.Item["owner"]
->…..

  • @JsonManagedReference is the forward part of reference – the one that gets serialized normally.
  • @JsonBackReference is the back part of reference – it will be omitted from serialization.

1
2
3
4
@JsonIdentityInfo(
  generator = ObjectIdGenerators.PropertyGenerator.class,
  property = "id")
public class User { ... }
And to the “Item” entity:
1
2
3
4
@JsonIdentityInfo(
  generator = ObjectIdGenerators.PropertyGenerator.class,
  property = "id")
public class Item { ... }
This might happen if you have two different instances of your class that have the same id. This would be something that you would have to fix in your code outside of what you have provided

https://github.com/FasterXML/jackson-databind/issues/266
  @JsonIdentityInfo(generator=ObjectIdGenerators.IntSequenceGenerator.class,property="@id",
       scope=OwnerScope.class)
  public User owner;

  @JsonIdentityInfo(generator=ObjectIdGenerators.IntSequenceGenerator.class,property="@id",
       scope=UserScope.class)
  public User user;

https://github.com/jsog/jsog-jackson
https://github.com/jsog/jsog

http://stackoverflow.com/questions/11664894/jackson-deserialize-using-generic-class
   JavaType type = mapper.getTypeFactory().constructParametricType(Data.class, contentClass.class);
   return mapper.readValue(json, type);
http://stackoverflow.com/questions/40166309/no-string-argument-constructor-factory-method-to-deserialize-from-string-value
no String-argument constructor/factory method to deserialize from String value
"multimedia" field is an empty string
So you need to verify your json and map you pojo accordingly.

http://stackoverflow.com/questions/24397647/jersey-exception-mappers-not-working-when-jackson-deserialization-fails
But there is one case in which neither my Exception mappers nor my json producing jsp are working, that is when sending a bad formed json to a POST REST endpoint which just returns the following message:
Can not deserialize instance of com.example.rest.User[] out of START_OBJECT token
 at [Source: org.glassfish.jersey.message.internal.EntityInputStream@1dcccac; line: 1, column: 1]

Update: changed JsonParseException to JsonProcessingException (more general)



Update2: In order to avoid registering the unwanted mappers replace

register(org.glassfish.jersey.jackson.JacksonFeature.class);

with

register(com.fasterxml.jackson.jaxrs.json.JacksonJaxbJsonProvider.class);

Look at the source code of JacksonFeature and you'll understand what's happening.
https://github.com/jersey/jersey/blob/master/media/json-jackson/src/main/java/org/glassfish/jersey/jackson/JacksonFeature.java

https://www.javacodegeeks.com/2013/04/how-to-use-propertynamingstrategy-in-jackson.html
https://blog.layer4.fr/2013/08/19/how-to-map-unknown-json-properties-with-jackson/
@JsonAnySetter is a simple marker that can be used to define a two-argument method (first argument name of property, second value to set), to be used as a “fallback” handler for all otherwise unrecognized properties found from JSON content.
http://stackoverflow.com/questions/10079617/handling-alternate-property-names-in-jackson-deserialization
ObjectMapper mapper = new ObjectMapper();
mapper.configure(MapperFeature.ACCEPT_CASE_INSENSITIVE_PROPERTIES, true);
http://stackoverflow.com/questions/8560348/different-names-of-json-property-during-serialization-and-deserialization
public class Coordinates {
    byte red;

    @JsonProperty("r")
    public byte getR() {
      return red;
    }

    @JsonProperty("red")
    public void setRed(byte red) {
      this.red = red;
    }
}
The idea is that method names should be different, so jackson parses it as different fields, not as one field.
Here is test code:
Coordinates c = new Coordinates();
c.setRed((byte) 5);

ObjectMapper mapper = new ObjectMapper();
System.out.println("Serialization: " + mapper.writeValueAsString(c));

Coordinates r = mapper.readValue("{\"red\":25}",Coordinates.class);
System.out.println("Deserialization: " + r.getR());

http://www.cowtowncoder.com/blog/archives/2011/07/entry_458.html

Thread-safe and performance
http://wiki.fasterxml.com/JacksonBestPracticesPerformance
http://wiki.fasterxml.com/ObjectReader

https://theartofdev.com/2014/07/20/jackson-objectmapper-performance-pitfall/
It raised my suspicion as everywhere else we use ObjectMapper as a static field so only a single instance is created.
After making a little tester (simplified version can be found below) I discovered that the using instance vs. static ObjectMapper field result in approximately x20 performance difference, that is the instance field usage is 20 times slower than static field!
Changing the ObjectMapper to static and re-running the test confirmed the issue, performance was significantly improved and the most expensive method became Proxy.newProxyInstance.

I can speculate that ObjectMapper uses reflection to create the POJO type from the string value, at least to find the constructor annotated with @JsonCreator. To improve performance ObjectMapper keeps some kind of caching per instance so creating a new instance each time requires ObjectMapper to do the expensive work each time.

http://wiki.fasterxml.com/JacksonFeaturesNonStandard

7. Prefer ObjectReader/ObjectWriter over ObjectMapper


Although the main reason to prefer these objects is thread-safety (and thus correctness), there may be performance benefits as well. Latest Jackson versions (2.1 and above) will be able to reuse root-level (de)serializers, making reuse of ObjectReaders and ObjectWriters bit more efficient than using ObjectMapper.


http://wiki.fasterxml.com/JacksonFAQThreadSafety
The basic rule of Jackson thread-safety is that factories follow "thread-safe after configuration" philosophy. This means that:
  • Configuring an instance is not synchronized or thread-safe, i.e. do not change settings while using it (which makes sense for other reasons too -- not all settings take effect once mapper has been in use, due to caching of serializers and deserializers)
  • Once configuration is complete, operation is fully thread-safe and synchronized in few places where that is needed, for symbol table and buffer reuse.
So as long as you first configure such factories from a single thread, and only then use it (from any number of threads), usage will be thread-safe without additional synchronization.
This rule specifically is used for:
  • ObjectMapper (and sub-classes)
  • JsonFactory (and sub-classes, like SmileFactory)
Note that more recently some new factory-like classes use "Fluent" pattern, whereby instances are immutable (and thus fully thread-safe!), and differently configured instances are constructed by factory methods. Specifically:
  • ObjectReader and ObjectWriter instances are immutable and thread-safe: they are created by ObjectMapper, and once constructed, their state NEVER CHANGES. To get instance with different configuration, one uses factory methods to create NEW INSTANCES (existing one is not changed). This allows complete thread-safe use at any point in life cycle.
This latter approach is preferred for future development, so new factory types will probably follow same style.

http://stackoverflow.com/questions/18611565/how-do-i-correctly-reuse-jackson-objectmapper

http://fasterxml.github.io/jackson-databind/javadoc/2.1.0/com/fasterxml/jackson/databind/ObjectReader.html
Builder object that can be used for per-serialization configuration of deserialization parameters, such as root type to use or object to update (instead of constructing new instance).




Uses "fluent" (or, kind of, builder) pattern so that instances are immutable (and thus fully thread-safe with no external synchronization); new instances are constructed for different configurations. Instances are initially constructed by ObjectMapper and can be reused, shared, cached; both because of thread-safety and because instances are relatively light-weight.


https://dzone.com/articles/how-serialize-javautildate
public class JsonDateSerializer extends JsonSerializer<Date>{
private static final SimpleDateFormat dateFormat = new SimpleDateFormat("MM-dd-yyyy");
@Override
public void serialize(Date date, JsonGenerator gen, SerializerProvider provider)
throws IOException, JsonProcessingException {
String formattedDate = dateFormat.format(date);
gen.writeString(formattedDate);
}
}

http://wiki.fasterxml.com/JacksonPolymorphicDeserialization

1.1. Global default typing

First, you can globally declare that certain types always require additional type information:
  // one of:
  objectMapper.enableDefaultTyping(); // default to using DefaultTyping.OBJECT_AND_NON_CONCRETE
  objectMapper.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL);
what this means is that for all types specified (for no-args, "Object.class" and all non-final classes), certain amount of default type information (Java class name, more specifically), is included, using default inclusion mechanism (additional wrapper array in JSON). This global default can be overridden by per-class annotations (more on this in next section).
The only thing you can configure, then, is just which types (classes) are affected. Choices are:
  • JAVA_LANG_OBJECT: only affects properties of type Object.class
  • OBJECT_AND_NON_CONCRETE: affects Object.class and all non-concrete types (abstract classes, interfaces)
  • NON_CONCRETE_AND+_ARRAYS: same as above, and all array types of the same (direct elements are non-concrete types or Object.class)
  • NON_FINAL: affects all types that are not declared 'final', and array types of non-final element types.

This is often simplest initial way to enable enough type information to get things going.

More granular (and powerful) way to define what type information to add, and where, is to use @JsonTypeInfo annotation (and possibly couple of related ones). For example, we could have annotated Animal as follows:
 @JsonTypeInfo(use=JsonTypeInfo.Id.CLASS, include=JsonTypeInfo.As.PROPERTY, property="@class")
 class Animal { } 
(which, incidentally is equivalent to the default settings for typing).
What does that mean?

  • All instances of annotated type and its subtypes use these settings (unless overridden by another annotation)
  • "Type identifier" to use is fully-qualified Java class name (like "org.codehaus.jackson.sample.Animal")
  • Type identifier is to be included as a (meta-)property, along with regular data properties; using name "@class" (default name to use depend on type if: for classes it would be "@class")
  • Use default type resolver (no @JsonTypeResolver added); as well as default type id resolver (no @JsonTypeIdResolver)

http://stackoverflow.com/questions/2525042/how-to-convert-a-json-string-to-a-mapstring-string-with-jackson-json
    ObjectMapper mapper = new ObjectMapper(); 
    File from = new File("albumnList.txt"); 
    TypeReference<HashMap<String,Object>> typeRef 
            = new TypeReference<HashMap<String,Object>>() {};

    HashMap<String,Object> o = mapper.readValue(from, typeRef); 
Map<String, String> result = new ObjectMapper().readValue(
    data, TypeFactory.mapType(HashMap.class, String.class, String.class));
On newer versions, try this: objectMapper.getTypeFactory().constructMapType(HashMap.class‌​, String.class, String.class));

JavaType javaType = objectMapper.getTypeFactory().constructParameterizedType(Map.class, Key.class, Value.class);
Map<Key, Value> map=objectMapper.readValue(jsonStr, javaType);
http://www.theotherian.com/2014/02/jackson-mixins-and-modules-external-classes.html
fixing recursive relationship issues with mixins
@JsonFilter("thing filter")
public class ThingMixin {
}
ObjectMapper mapper = new ObjectMapper();
mapper.addMixInAnnotations(Thing.class, ThingMixin.class);
FilterProvider filterProvider = new SimpleFilterProvider()
  .addFilter("thing filter", SimpleBeanPropertyFilter.serializeAllExcept("user"));
mapper.setFilters(filterProvider);

fixing classes that don't conform to the bean spec with modules and customer serializers
public class WidgetNameSerializer extends JsonSerializer<WidgetName> {

  @Override
  public void serialize(WidgetName widgetName, JsonGenerator jgen, SerializerProvider provider) throws IOException,
      JsonProcessingException {
    jgen.writeString(widgetName.value());
  }
}

http://www.cowtowncoder.com/blog/archives/2011/02/entry_443.html
3. Explicitly ignoring properties: @JsonIgnore, @JsonIgnoreProperties
5. Ignoring all properties with specified type: @JsonIgnoreType
In addition to defining rules on per-property basis, there are times when it makes sense to just prevent serialization of any auto-detected properties for given type(s). For example, many frameworks add specific accessors for types they generate, which return objects that should not be serialized.
SON Filters are a way to implement fully dynamic filtering. The way this is done is by defining logical filter a property uses, with @JsonFilter("id") annotation, but specifying actual filter (and its configuration) using ObjectWriter. Filters themselves are obtained via FilterProviders which can be fully custom, or based on simple implementations

2. Configuring mapping from id to filter instance
Of mechanisms, latter one may be easier to understand and use: one just has to implement 'FilterProvider', which has but one method to implement:
  public abstract class FilterProvider {
    public abstract BeanPropertyFilter findFilter(Object filterId);
  }
given this, 'SimpleFilterProvider' is little more than a Map<String,BeanPropertyFilter>, except for adding couple of convenience factory methods that build 'SimpleBeanPropertyFilter' instances given property names, so you typically just instantiate one with calls like:
  SimpleBeanPropertyFilter filter = SimpleBeanPropertyFilter.filterOutAllExcept("a"));
which would out all properties except for one named "a". This filter is then configured with ObjectMapper like so:
  FilterProvider fp = new SimpleFilterProvider().addFilter("onlyAFilter", filter);
  objectMapper.writer(fp).writeValueAsString(pojo);
which would, then, apply to any Java type configured to use filter with id "onlyAFilter".
3. Configuring discovery of filter id
From above example we know we need to indicate classes that are to use our "onlyAFilter". The default mechanism is to use:
  @JsonFilter("onlyAFilter")
  public class FilteredPOJO {
    //...
  }
But this is just the default. How so? The way Jackson figures out its annotation-based configuration is actually indirect, and fully customizable: all interaction is through configured 'AnnotationIntrospector' object, which amongst other things defines this method:
  public Object findFilterId(AnnotatedClass ac);
which is called when serializer needs to determine id of the filter to apply (if any) for given class. Since the default implementation (org.codehaus.jackson.map.introspect.JacksonAnnotationIntrospector) has everything else working fine, what we can do is to sub-class it and override this method.
For example:
  public class MyFilteringIntrospector extends JacksonAnnotationIntrospector
  {
    @Override
    public Object findFilterId(AnnotatedClass ac) {
      // First, let's consider @JsonFilter by calling superclass
      Object id = super.findFilterId(ac);
      // but if not found, use our own heuristic; say, just use class name as filter id, if there's "Filter" in name:
      if (id == null) {
        String name = ac.getName();
        if (name.indexOf("Filter") >= 0) {
          id = name;
        }
      }
      return id;
    }
  }
http://www.cowtowncoder.com/blog/archives/2011/09/entry_461.html


https://github.com/PressAssociation/partial-response/tree/master/filter-json-jackson
https://jira.spring.io/browse/SPR-7156
http://javaactive.blogspot.com/2014/05/how-to-implement-jackson-filters-to.html
@JsonFilter(com.test.ProductModel)  
public class ProductModel implements IModel {  
    private String id ;  
    private String name ;  
    ....  
    ....  
    ...getter and setter methods...
}

Filtering mechanism

 public static String filterJsonFields(IModel model,  
  String jsonFilter, String fieldsQueryParam) throws IOException { 
          
    String jsonResult = null ;  
    SimpleBeanPropertyFilter filter = SimpleBeanPropertyFilter.  
                     serializeAllExcept(Collections.<String> emptySet());  
    Set<String> filterProps = new HashSet<String>();      
    if (fieldsQueryParam != null) {  
        StringTokenizer st = new StringTokenizer(fieldsQueryParam, "," );  
        while (st.hasMoreTokens()) {  
            filterProps.add(st.nextToken());  
        }  
        filter = SimpleBeanPropertyFilter.filterOutAllExcept(filterProps);  
    }         
    ObjectMapper mapper = new ObjectMapper();  
    FilterProvider fProvider = new SimpleFilterProvider().addFilter(jsonFilter, filter)  
                        // setFailOnUnknownId: Ignore filtering the reference member fields  
                        // Refer: https://jira.codehaus.org/browse/JACKSON-650  
                        .setFailOnUnknownId( false );  
    try {  
        jsonResult = mapper.writer(fProvider).writeValueAsString(model);  
    } catch (IOException e) {  
        throw e;  
    }  
    return jsonResult;  
}   

http://www.baeldung.com/jackson-serialize-field-custom-criteria
@JsonFilter("myFilter")
PropertyFilter theFilter = new SimpleBeanPropertyFilter() {
   @Override
   public void serializeAsField
    (Object pojo, JsonGenerator jgen, SerializerProvider provider, PropertyWriter writer)
     throws Exception {
      if (include(writer)) {
         if (!writer.getName().equals("intValue")) {
            writer.serializeAsField(pojo, jgen, provider);
            return;
         }
         int intValue = ((MyDtoWithFilter) pojo).getIntValue();
         if (intValue >= 0) {
            writer.serializeAsField(pojo, jgen, provider);
         }
      } else if (!jgen.canOmitFields()) { // since 2.3
         writer.serializeAsOmittedField(pojo, jgen, provider);
      }
   }
   @Override
   protected boolean include(BeanPropertyWriter writer) {
      return true;
   }
   @Override
   protected boolean include(PropertyWriter writer) {
      return true;
   }
};

FilterProvider filters = new SimpleFilterProvider().addFilter("myFilter", theFilter);
MyDto dtoObject = new MyDto();
dtoObject.setIntValue(-1);
ObjectMapper mapper = new ObjectMapper();
String dtoAsString = mapper.writer(filters).writeValueAsString(dtoObject);
http://www.jroller.com/RickHigh/entry/filtering_json_feeds_from_spring
@JsonIgnoreProperties( { "country",
})
@JsonPropertyOrder(value={"title", "id", "version",  "price", "summary"})
public interface AppDetailFilter {

}
@JsonFilter(mixin=AppDetailFilter.class)
http://stackoverflow.com/questions/28270621/using-jackson-to-de-serialize-a-scala-case-class
Using Jackson to (De)-serialize a Scala Case Class
Jackson is expecting your class to be a JavaBean, which means its expects the class to have a getX() and/or setX() for every property.
Option 1
You can create JavaBean classes in Scala using the annotation BeanProperty.
Example
case class Person(
   @BeanProperty val name: String, 
   @BeanProperty val age: Int, 
   @BeanProperty val hobbies: Option[String]
)
In this case a val will mean only a getter is defined. If you want setters for deserialization you defined the properties as var.
Option 2
While option 1 will work, if you really want to use Jackson there are wrappers that allow it to deal with Scala classes like FasterXML's scala module which might be a better approach. I haven't used it as I've just been using the Json library built in to play.
https://www.mkyong.com/java/jackson-streaming-api-to-read-and-write-json/
Jackson supports read and write JSON via high-performance Jackson Streaming APIs, or incremental mode.

Jackson’s streaming processing is high-performance, fast and convenient, but it’s also difficult to use, because you need to handle each and every detail of JSON data.

JsonSerializer - SerializerProvider serializer
serializer.defaultSerializeValue(oct, jGen);
https://dzone.com/articles/latest-jackson-integration
Jackson2ObjectMapperBuilder

http://programmerbruce.blogspot.com/2011/05/deserialize-json-with-jackson-into.html
  1.     Collection<Animal> animals =  
  2.       mapper.readValue(new File("input_2.json"),  
  3.         new TypeReference<Collection<Animal>>() {});  
  4.     System.out.println(mapper.writeValueAsString(animals));  
  5.     // or  
  6.     Collection<Animal> animals2 =  
  7.       mapper.readValue(new File("input_2.json"),  
  8.         TypeFactory.defaultInstance().constructParametricType(  
  9.             Collection.class, Animal.class));  
https://github.com/FasterXML/jackson-databind/blob/master/src/main/java/com/fasterxml/jackson/databind/MapperFeature.java
USE_ANNOTATIONS(true),

How to ignore pojo annotations while using Jackson ObjectMapper?
http://stackoverflow.com/questions/31680046/how-to-ignore-pojo-annotations-while-using-jackson-objectmapper
ObjectMapper objectMapper = new ObjectMapper().configure(
                 org.codehaus.jackson.map.DeserializationConfig.Feature.USE_ANNOTATIONS, false)                    .configure(org.codehaus.jackson.map.SerializationConfig.Feature.USE_ANNOTATIONS, false);
http://www.baeldung.com/jackson-ignore-properties-on-serialization
@JsonProperty("anotherName")
@JsonIgnoreProperties(value = { "someField" })
@JsonIgnore
@JsonIgnoreType
public class SomeType { ... }

@JsonProperty("strVal")
public String getStringValue() {
http://www.baeldung.com/jackson-exception
This exception is thrown if Jackson can’t create instance of the class – this happens if the class is abstract or it is just an interface.
http://www.baeldung.com/jackson-serialize-dates
Jackson will serialize the Date to a timestamp format by default (number of milliseconds since January 1st, 1970, UTC).

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

    SimpleDateFormat df = new SimpleDateFormat("dd-MM-yyyy hh:mm");
    ObjectMapper mapper = new ObjectMapper();
    mapper.setDateFormat(df);

http://www.leveluplunch.com/java/tutorials/033-custom-jackson-date-deserializer/

    ObjectMapper objectMapper = new ObjectMapper();

    SimpleModule simpleModule = new SimpleModule();
    simpleModule.addDeserializer(Object.class, new CustomDateDeseralizer());
    objectMapper.registerModule(simpleModule);

ObjectMapper is thread safe. You only need one instance of it for for each configuration, i.e., if you need 2 different date formats, then you need 2 ObjectMapper objects, or only one but you need to synchronizethe call to the setDateFormat method.

https://github.com/FasterXML/jackson-datatype-guava
ObjectMapper mapper = new ObjectMapper()
    .registerModule(new GuavaModule());
http://stackoverflow.com/questions/25693309/using-jackson-objectmapper-with-java-8-optional-values
ObjectMapper mapper = new ObjectMapper();
mapper.addMixInAnnotations(Optional.class, OptionalMixin.class);
You could use jackson-datatype-jdk8 which is described as:
Support for new JDK8-specific types, such as Optional
How to enable pretty print JSON output (Jackson)
To enable pretty print, use writerWithDefaultPrettyPrinter.
System.out.println(mapper.writerWithDefaultPrettyPrinter().writeValueAsString(user));
http://www.baeldung.com/jackson-ignore-properties-on-serialization
    @JsonIgnore
    private int intValue;
5. Ignore fields using Filters
@JsonFilter("myFilter")
public class MyDtoWithFilter { ... }
SimpleBeanPropertyFilter theFilter = SimpleBeanPropertyFilter.serializeAllExcept("intValue");
FilterProvider filters = new SimpleFilterProvider().addFilter("myFilter", theFilter);
    ObjectMapper mapper = new ObjectMapper();
    SimpleBeanPropertyFilter theFilter = SimpleBeanPropertyFilter.serializeAllExcept("intValue");
    FilterProvider filters = new SimpleFilterProvider().addFilter("myFilter", theFilter);
    MyDtoWithFilter dtoObject = new MyDtoWithFilter();
http://www.cowtowncoder.com/blog/archives/2011/02/entry_443.html
4. Defining profiles for dynamic ignoral: JSON Views (@JsonView)
          // Name is public
            @JsonView(Views.Public.class) String name;
            // Address semi-public
            @JsonView(Views.ExtendPublic.class) Address address;
            // SSN only for internal usage
            @JsonView(Views.Internal.class) SocialSecNumber ssn;
 // or, starting with 1.5, more convenient (ObjectWriter is reusable too)
  objectMapper.viewWriter(ViewsPublic.class).writeValue(out, beanInstance);
Views with JAX-RS
      @JsonView(Views.Public.class)
      @GET
      @Produces(MediaType.APPLICATION_JSON )
      public List<Object> getElements() {

By default all properties without explicit view definition are included in serialization.
http://stackoverflow.com/questions/16089651/jackson-serialization-ignore-empty-values-or-null
Jackson allows controlling this behavior at either the class level or field level.
@JsonInclude(Include.NON_NULL)
@JsonInclude(Include.NON_NULL)  
public static class Request {
    ...
}
The other option is to configure the ObjectMapper directly, simply by calling objectMapper.setSerializationInclusion(JsonInclude.Include.NON_NULL);
http://stackoverflow.com/questions/39005703/jackson-annotations-difference-between-jsonignorepropertiesignoreunknown-true
@JsonInclude(Include.NON_EMPTY)
public static class Person {
    [....]
}
Console output is: {"firstName":"Mark","lastName":"Watney"}
http://stackoverflow.com/questions/21048020/jackson-jsonview-not-being-applied
Good catch regarding withView() not mutating the existing config. However,objectMapper.setConfig(objectMapper.getSerializationConfig().withView(YourView.‌​class));works and is probably prefarable to subclassing ObjectMappe
Turns out if you actually read the docs you find out that you can't just change serialization configuration by calling getSerializationConfig and calling setters on it.
you can NOT change settings by accessing an instance and calling methods:
http://stackoverflow.com/questions/18043587/why-im-not-able-to-unwrapp-and-serialize-java-map-using-jackson-java-library
http://wiki.fasterxml.com/JacksonFeatureAnyGetter
@JsonUnwrapped doesn't work for maps, only for proper POJOs with getters and setters. For maps, You should use @JsonAnyGetter and @JsonAnySetter (available in jackson version >= 1.6).
    private void HashMap<String, String> properties;

    @JsonAnySetter public void add(String key, String value) {
      properties.put(key, value);
    }

    @JsonAnyGetter public Map<String,String> getProperties() {
      return properties;
    }
http://code-willy.blogspot.com/2013/03/jersey-client-with-customize-json.html
Jersey Client with Customize JSON (Jackson) Configuration
    ClientConfig clientConfig = new DefaultClientConfig();
    // Allow Jersey Client support JSON.
    clientConfig.getFeatures().put(JSONConfiguration.FEATURE_POJO_MAPPING, Boolean.TRUE);   
    // Create your own Jackson ObjectMapper.
    ObjectMapper mapper = new ObjectMapper();
    mapper.configure(DeserializationConfig.Feature.FAIL_ON_UNKNOWN_PROPERTIES, false);
    // Create your own JacksonJaxbJsonProvider and then assign it to the config.
    JacksonJaxbJsonProvider jacksonProvider = new JacksonJaxbJsonProvider();
    jacksonProvider.setMapper(mapper);
    clientConfig.getSingletons().add(jacksonProvider); 

    Client client = Client.create(clientConfig); 

@JsonAutoDetect(fieldVisibility = Visibility.ANY, getterVisibility = Visibility.NONE, setterVisibility = Visibility.NONE)
Custom JSON Deserialization with Jackson
https://dzone.com/articles/custom-json-deserialization-with-jackson
public class ProgramDeserializer extends JsonDeserializer<Program> {
  @Override
  public Program deserialize(JsonParser jp, DeserializationContext ctxt) throws IOException, JsonProcessingException {
    ObjectCodec oc = jp.getCodec();
    JsonNode node = oc.readTree(jp);
    final Long id = node.get("id").asLong();
    final String name = node.get("name").asText();
    final String contents = node.get("contents").asText();
    final long ownerId = node.get("ownerId").asLong();
    User user = new User();
    user.setId(ownerId);
    return new Program(id, name, contents, user);
  }
}
ObjectMapper mapper = new ObjectMapper();
SimpleModule module = new SimpleModule();
module.addDeserializer(Program.class, new ProgramDeserializer());
mapper.registerModule(module);

http://wiki.fasterxml.com/JacksonFeatureUnwrapping
@JsonUnwrapped public Location location;
which we would like to bind to (or from) JSON like:
  {
    "name" : "home",
    "latitude" : 127,
    "longitude" : 345
  }


@JsonInclude(Include.NON_NULL)
Jackson supports annotation inheritance.
http://wiki.fasterxml.com/JacksonFAQDateHandling
objectMapper.configure(SerializationConfig.Feature.WRITE_DATES_AS_TIMESTAMPS, false);
which disable use of timestamps (numbers), and instead use a [ISO-8601 ]-compliant notation, which gets output as something like: "1970-01-01T00:00:00.000+0000".
That format sucks, can I use my own?
If you must. You can configure formatting by passing a java.text.DateFormat instance like so:

  objectMapper.setDateFormat(myDateFormat); // 1.8 and above  objectMapper.getSerializationConfig().setDateFormat(myDateFormat); // for earlier versions (deprecated for 1.8+)
Can I configure it on per-property basis?
Yes, with Jackson 2.0 you can use the new @JsonFormat annotation:
  public class DateStuff {
    @JsonFormat(shape=JsonFormat.Shape.STRING, pattern="yyyy-MM-dd,HH:00", timezone="CET")
    public Date creationTime;
  }

http://stackoverflow.com/questions/20563640/using-jackson-objectmapper-with-jersey
@Provider
public class JerseyMapperProvider implements ContextResolver<ObjectMapper> {
    private static ObjectMapper apiMapper = ObjectMapperManager.createMapperForApi();
    @Override
    public ObjectMapper getContext(Class<?> type)
    {
        return apiMapper;
    }
}

    @JsonCreator
    public static Test1 factory(double n) {
        return new Test1(n);
    }
http://wahdancsthoughts.blogspot.com/2013/06/json-polymorphic-types-with-jackson.html
@JsonTypeInfo(
    use = JsonTypeInfo.Id.NAME,
    include = JsonTypeInfo.As.PROPERTY,
    property = "type")
@JsonSubTypes({
    @Type(value = Cat.class, name = "cat"),
    @Type(value = Dog.class, name = "dog") })

http://www.mkyong.com/java/how-to-convert-java-map-to-from-json-jackson/
   map = mapper.readValue(json, new TypeReference<Map<String, String>>(){});
   json = mapper.writerWithDefaultPrettyPrinter().writeValueAsString(map);
JavaType collectionType = mapper.getTypeFactory().constructCollectionType(List.class, MyObject.class);
List<MyObject> readValue = mapper.readValue(jsonString, collectionType);

http://www.baeldung.com/jackson-collection-array
MyDto[] asArray = mapper.readValue(jsonArray, MyDto[].class);
MyDto class needs to have the no-args default constructor – if it doesn’t, Jackson will not be able to instantiate it:
http://tutorials.jenkov.com/java-json/jackson-annotations.html
The @JsonIgnoreType Jackson annotation is used to mark a whole type (class) to be ignored everywhere that type is used. Here is an example that shows you how you could use the @JsonIgnoreType annotation:

@JsonSetter

The Jackson annotation @JsonSetter is used to tell Jackson that is should match the name of this setter method to a property name in the JSON data, when reading JSON into objects. This is useful if the property names used internally in your Java class is not the same as the property name used in the JSON file.
    @JsonSetter("id")
    public void setPersonId(long personId) { this.personId = personId; }

@JsonAnySetter

The Jackson annotation @JsonAnySetter instructs Jackson to call the same setter method for all unrecognized fields in the JSON object. By "unrecognized" I mean all fields that are not already mapped to a property or setter method in the Java object
public class Bag {

    private Map<String, Object> properties = new HashMap<>();

    @JsonAnySetter
    public void set(String fieldName, Object value){
        this.properties.put(fieldName, value);
    }

    public Object get(String fieldName){
        return this.properties.get(fieldName);
    }
}

@JsonCreator

The Jackson annotation @JsonCreator is used to tell Jackson that the Java object has a constructor (a "creator") which can match the fields of a JSON object to the fields of the Java object.
The @JsonCreator annotation is useful in situations where the @JsonSetter annotation cannot be used. For instance, immutable objects do not have any setter methods, so they need their initial values injected into the constructor. Look at this PersonImmutable class as example:
    @JsonCreator
    public PersonImmutable(
            @JsonProperty("id")  long id,
            @JsonProperty("name") String name  ) {

        this.id = id;
        this.name = name;
    }

    @JsonGetter("id")
    public long personId() { return this.personId; }

    @JsonSetter("id")
    public void personId(long personId) { this.personId = personId; }

@JsonAnyGetter

The @JsonAnyGetter Jackson annotation enables you to use a Map as container for properties that you want to serialize to JSON. Here is an example of using the @JsonAnyGetter annotation in a Java class:
public class PersonAnyGetter {

    private Map<String, Object> properties = new HashMap<>();

    @JsonAnyGetter
    public Map<String, Object> properties() {
        return properties;
    }
}
@JsonPropertyOrder({"name", "personId"})
Normally Jackson would have serialized the properties in PersonPropertyOrder in the sequence they are found in the class.

@JsonRawValue

The @JsonRawValue Jackson annotation tells Jackson that this property value should written directly as it is to the JSON output. If the property is a String Jackson would normally have enclosed the value in quotation marks, but if annotated with the @JsonRawValue property Jackson won't do that.
    @JsonRawValue
    public String address  =
            "{ \"street\" : \"Wall Street\", \"no\":1}";
http://tutorials.jenkov.com/java-json/jackson-objectmapper.html

CSV
https://github.com/FasterXML/jackson-dataformat-csv
// Schema from POJO (usually has @JsonPropertyOrder annotation)
CsvSchema schema = mapper.schemaFor(Pojo.class);

// Manually-built schema: one with type, others default to "STRING"
CsvSchema schema = CsvSchema.builder()
        .addColumn("firstName")
        .addColumn("lastName")
        .addColumn("age", CsvSchema.ColumnType.NUMBER)
        .build();

// Read schema from the first line; start with bootstrap instance
// to enable reading of schema from the first line
// NOTE: reads schema and uses it for binding
CsvSchema bootstrapSchema = CsvSchema.emptySchema().withHeader();
ObjectMapper mapper = new CsvMapper();
mapper.readerFor(Pojo.class).with(bootstrapSchema).readValue(json);

CSV content can be read either using CsvFactory (and parser, generators it creates) directly, or through CsvMapper(extension of standard ObjectMapper).
When using CsvMapper, you will be creating ObjectReader or ObjectWriter instances that pass CsvSchema along toCsvParser / CsvGenerator. When creating parser/generator directly, you will need to explicitly call setSchema(schema)before starting to read/write content.
The most common method for reading CSV data, then, is:
CsvMapper mapper = new CsvMapper();
Pojo value = ...;
CsvSchema schema = mapper.schemaFor(Pojo.class); // schema from 'Pojo' definition
String csv = mapper.writer(schema).writeValueAsString(value);
Pojo result = mapper.readerFor(Pojo.class).with(schema).read(csv);
http://blog.xyleolabs.com/2015/05/making-your-jersey-client-post-csv-data.html
http://stackoverflow.com/questions/31685653/spring-boot-jersey-jackson/31703546#31703546
    public ObjectMapperContextResolver() {
        mapper = new ObjectMapper();
        mapper.setPropertyNamingStrategy(
            PropertyNamingStrategy.CAMEL_CASE_TO_LOWER_CASE_WITH_UNDERSCORES
        );
    }
http://notes.stay4it.com/2016/02/29/http-related-mess-json-data-response/
http://stackoverflow.com/questions/21787128/how-to-unit-test-jackson-jsonserializer-and-jsondeserializer
    private ObjectMapper mapper;
    private CustomerNumberDeserialiser deserializer;

    @Before
    public void setup() {
        mapper = new ObjectMapper();
        deserializer = new CustomerNumberDeserialiser();
    }

    @Test
    public void floating_point_string_deserialises_to_Double_value() {
        String json = String.format("{\"value\":%s}", "\"1.1\"");
        Number deserialisedNumber = deserialiseNumber(json);
        assertThat(deserialisedNumber, instanceOf(Double.class));
        assertThat(deserialisedNumber, is(equalTo(1.1d)));
    }

    @SneakyThrows({JsonParseException.class, IOException.class})
    private Number deserialiseNumber(String json) {
        InputStream stream = new ByteArrayInputStream(json.getBytes(StandardCharsets.UTF_8));
        JsonParser parser = mapper.getFactory().createParser(stream);
        DeserializationContext ctxt = mapper.getDeserializationContext();
        parser.nextToken();
        parser.nextToken();
        parser.nextToken();
        return deserializer.deserialize(parser, ctxt);
    }

Labels

Review (572) System Design (334) System Design - Review (198) Java (189) Coding (75) Interview-System Design (65) Interview (63) Book Notes (59) Coding - Review (59) to-do (45) Linux (43) Knowledge (39) Interview-Java (35) Knowledge - Review (32) Database (31) Design Patterns (31) Big Data (29) Product Architecture (28) MultiThread (27) Soft Skills (27) Concurrency (26) Cracking Code Interview (26) Miscs (25) Distributed (24) OOD Design (24) Google (23) Career (22) Interview - Review (21) Java - Code (21) Operating System (21) Interview Q&A (20) System Design - Practice (20) Tips (19) Algorithm (17) Company - Facebook (17) Security (17) How to Ace Interview (16) Brain Teaser (14) Linux - Shell (14) Redis (14) Testing (14) Tools (14) Code Quality (13) Search (13) Spark (13) Spring (13) Company - LinkedIn (12) How to (12) Interview-Database (12) Interview-Operating System (12) Solr (12) Architecture Principles (11) Resource (10) Amazon (9) Cache (9) Git (9) Interview - MultiThread (9) Scalability (9) Trouble Shooting (9) Web Dev (9) Architecture Model (8) Better Programmer (8) Cassandra (8) Company - Uber (8) Java67 (8) Math (8) OO Design principles (8) SOLID (8) Design (7) Interview Corner (7) JVM (7) Java Basics (7) Kafka (7) Mac (7) Machine Learning (7) NoSQL (7) C++ (6) Chrome (6) File System (6) Highscalability (6) How to Better (6) Network (6) Restful (6) CareerCup (5) Code Review (5) Hash (5) How to Interview (5) JDK Source Code (5) JavaScript (5) Leetcode (5) Must Known (5) Python (5)

Popular Posts