View Javadoc
1   package top.infra.jackson2;
2   
3   import com.fasterxml.jackson.databind.AnnotationIntrospector;
4   import com.fasterxml.jackson.databind.BeanDescription;
5   import com.fasterxml.jackson.databind.JavaType;
6   import com.fasterxml.jackson.databind.JsonSerializer;
7   import com.fasterxml.jackson.databind.SerializationConfig;
8   import com.fasterxml.jackson.databind.introspect.AnnotatedClass;
9   import com.fasterxml.jackson.databind.jsontype.NamedType;
10  import com.fasterxml.jackson.databind.jsontype.TypeResolverBuilder;
11  import com.fasterxml.jackson.databind.jsontype.TypeSerializer;
12  import com.fasterxml.jackson.databind.ser.Serializers;
13  
14  import org.apache.commons.lang3.tuple.Pair;
15  
16  import java.util.Collection;
17  
18  import top.infra.jackson2.ser.PairSerializer;
19  
20  /**
21   * {@link com.fasterxml.jackson.databind.ser.BasicSerializerFactory#buildMapEntrySerializer(SerializationConfig, JavaType, BeanDescription, boolean, JavaType, JavaType)}.
22   * {@link com.fasterxml.jackson.databind.ser.BeanSerializerFactory}
23   * com.fasterxml.jackson.datatype.guava.GuavaSerializers
24   */
25  public class CommonsLangSerializers extends Serializers.Base {
26  
27      @Override
28      public JsonSerializer<?> findSerializer(
29          final SerializationConfig config, final JavaType type, final BeanDescription beanDesc) {
30          // see: BasicSerializerFactory.buildContainerSerializer
31          if (Pair.class.isAssignableFrom(type.getRawClass())) {
32              // Let's see what we can learn about element/content/value type, type serializer for it:
33              JavaType lType = type.containedTypeOrUnknown(0);
34              JavaType rType = type.containedTypeOrUnknown(1);
35              boolean staticTyping = false;
36              final TypeSerializer kts = createTypeSerializer(config, lType);
37              final TypeSerializer vts = createTypeSerializer(config, rType);
38              return new PairSerializer(type, lType, rType, staticTyping, kts, vts, null);
39          }
40          return super.findSerializer(config, type, beanDesc);
41      }
42  
43      /**
44       * see: {@link com.fasterxml.jackson.databind.ser.BasicSerializerFactory#createTypeSerializer(SerializationConfig, JavaType)}.
45       */
46      public TypeSerializer createTypeSerializer(final SerializationConfig config, final JavaType baseType) {
47          if (baseType == null) {
48              return null;
49          }
50          final BeanDescription bean = config.introspectClassAnnotations(baseType.getRawClass());
51          final AnnotatedClass ac = bean.getClassInfo();
52          final AnnotationIntrospector ai = config.getAnnotationIntrospector();
53          TypeResolverBuilder<?> b = ai.findTypeResolver(config, ac, baseType);
54          /* Ok: if there is no explicit type info handler, we may want to
55           * use a default. If so, config object knows what to use.
56           */
57          Collection<NamedType> subtypes = null;
58          if (b == null) {
59              b = config.getDefaultTyper(baseType);
60          } else {
61              subtypes = config.getSubtypeResolver().collectAndResolveSubtypesByClass(config, ac);
62          }
63          if (b == null) {
64              return null;
65          }
66          // 10-Jun-2015, tatu: Since not created for Bean Property, no need for post-processing
67          //    wrt EXTERNAL_PROPERTY
68          return b.buildTypeSerializer(config, baseType, subtypes);
69      }
70  }