下面列出了怎么用com.fasterxml.jackson.databind.AnnotationIntrospector的API类实例代码及写法,或者点击链接到github查看源代码。
@Override
public Collection<NamedType> collectAndResolveSubtypesByClass(MapperConfig<?> config,
AnnotatedClass type)
{
final AnnotationIntrospector ai = config.getAnnotationIntrospector();
HashMap<NamedType, NamedType> subtypes = new HashMap<NamedType, NamedType>();
// then consider registered subtypes (which have precedence over annotations)
if (_registeredSubtypes != null) {
Class<?> rawBase = type.getRawType();
for (NamedType subtype : _registeredSubtypes) {
// is it a subtype of root type?
if (rawBase.isAssignableFrom(subtype.getType())) { // yes
AnnotatedClass curr = AnnotatedClassResolver.resolveWithoutSuperTypes(config,
subtype.getType());
_collectAndResolve(curr, subtype, config, ai, subtypes);
}
}
}
// and then check subtypes via annotations from base type (recursively)
NamedType rootType = new NamedType(type.getRawType(), null);
_collectAndResolve(type, rootType, config, ai, subtypes);
return new ArrayList<NamedType>(subtypes.values());
}
@Override
public JsonFormat.Value findPropertyFormat(MapperConfig<?> config, Class<?> baseType)
{
// 15-Apr-2016, tatu: Let's calculate lazily, retain; assumption being however that
// baseType is always the same
JsonFormat.Value v = _propertyFormat;
if (v == null) {
JsonFormat.Value v1 = config.getDefaultPropertyFormat(baseType);
JsonFormat.Value v2 = null;
AnnotationIntrospector intr = config.getAnnotationIntrospector();
if (intr != null) {
AnnotatedMember member = getMember();
if (member != null) {
v2 = intr.findFormat(member);
}
}
if (v1 == null) {
v = (v2 == null) ? EMPTY_FORMAT : v2;
} else {
v = (v2 == null) ? v1 : v1.withOverrides(v2);
}
_propertyFormat = v;
}
return v;
}
@Override
public JsonInclude.Value findPropertyInclusion(MapperConfig<?> config, Class<?> baseType)
{
AnnotationIntrospector intr = config.getAnnotationIntrospector();
AnnotatedMember member = getMember();
if (member == null) {
JsonInclude.Value def = config.getDefaultPropertyInclusion(baseType);
return def;
}
JsonInclude.Value v0 = config.getDefaultInclusion(baseType, member.getRawType());
if (intr == null) {
return v0;
}
JsonInclude.Value v = intr.findPropertyInclusion(member);
if (v0 == null) {
return v;
}
return v0.withOverrides(v);
}
@Override
public List<PropertyName> findAliases(MapperConfig<?> config)
{
List<PropertyName> aliases = _aliases;
if (aliases == null) {
AnnotationIntrospector intr = config.getAnnotationIntrospector();
if (intr != null) {
aliases = intr.findPropertyAliases(getMember());
}
if (aliases == null) {
aliases = Collections.emptyList();
}
_aliases = aliases;
}
return aliases;
}
/**
* Factory method for constructing resolver that maps from Enum.name() into
* Enum value
*/
public static EnumResolver constructFor(Class<Enum<?>> enumCls, AnnotationIntrospector ai)
{
Enum<?>[] enumValues = enumCls.getEnumConstants();
if (enumValues == null) {
throw new IllegalArgumentException("No enum constants for class "+enumCls.getName());
}
String[] names = ai.findEnumValues(enumCls, enumValues, new String[enumValues.length]);
HashMap<String, Enum<?>> map = new HashMap<String, Enum<?>>();
for (int i = 0, len = enumValues.length; i < len; ++i) {
String name = names[i];
if (name == null) {
name = enumValues[i].name();
}
map.put(name, enumValues[i]);
}
Enum<?> defaultEnum = ai.findDefaultEnumValue(enumCls);
return new EnumResolver(enumCls, enumValues, map, defaultEnum);
}
/**
* @since 2.9
*/
public static EnumResolver constructUsingMethod(Class<Enum<?>> enumCls,
AnnotatedMember accessor,
AnnotationIntrospector ai)
{
Enum<?>[] enumValues = enumCls.getEnumConstants();
HashMap<String, Enum<?>> map = new HashMap<String, Enum<?>>();
// from last to first, so that in case of duplicate values, first wins
for (int i = enumValues.length; --i >= 0; ) {
Enum<?> en = enumValues[i];
try {
Object o = accessor.getValue(en);
if (o != null) {
map.put(o.toString(), en);
}
} catch (Exception e) {
throw new IllegalArgumentException("Failed to access @JsonValue of Enum value "+en+": "+e.getMessage());
}
}
Enum<?> defaultEnum = (ai != null) ? ai.findDefaultEnumValue(enumCls) : null;
return new EnumResolver(enumCls, enumValues, map, defaultEnum);
}
/**
* Creates an Endpoints standard object mapper that allows unquoted field names and unknown
* properties.
*
* Note on unknown properties: When Apiary FE supports a strict mode where properties
* are checked against the schema, BE can just ignore unknown properties. This way, FE does
* not need to filter out everything that the BE doesn't understand. Before that's done,
* a property name with a typo in it, for example, will just be ignored by the BE.
*/
public static ObjectMapper createStandardObjectMapper(ApiSerializationConfig config) {
ObjectMapper objectMapper = new ObjectMapper()
.configure(JsonParser.Feature.ALLOW_COMMENTS, true)
.configure(JsonParser.Feature.ALLOW_SINGLE_QUOTES, true)
.configure(JsonParser.Feature.ALLOW_UNQUOTED_FIELD_NAMES, true)
.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false)
.setBase64Variant(Base64Variants.MODIFIED_FOR_URL)
.setSerializerFactory(
BeanSerializerFactory.instance.withSerializerModifier(new DeepEmptyCheckingModifier()));
AnnotationIntrospector pair = EndpointsFlag.JSON_USE_JACKSON_ANNOTATIONS.isEnabled()
? AnnotationIntrospector.pair(
new ApiAnnotationIntrospector(config),
new JacksonAnnotationIntrospector())
: new ApiAnnotationIntrospector(config);
objectMapper.setAnnotationIntrospector(pair);
return objectMapper;
}
@Override
public ObjectMapper get()
{
ObjectMapper mapper = objectMapper;
if (mapper == null) {
final GuiceAnnotationIntrospector guiceIntrospector = new GuiceAnnotationIntrospector();
AnnotationIntrospector defaultAI = new JacksonAnnotationIntrospector();
MapperBuilder<?,?> builder = JsonMapper.builder()
.injectableValues(new GuiceInjectableValues(injector))
.annotationIntrospector(new AnnotationIntrospectorPair(guiceIntrospector, defaultAI))
.addModules(modulesToAdd);
for (Provider<? extends Module> provider : providedModules) {
builder = builder.addModule(provider.get());
}
mapper = builder.build();
/*
} else {
// 05-Feb-2017, tatu: _Should_ be fine, considering instances are now (3.0) truly immutable.
// But if this turns out to be problematic, may need to consider addition of `copy()`
// back in databind
mapper = mapper.copy();
*/
}
return mapper;
}
@Override
public void init(EndpointConfig config) {
mapper = new ObjectMapper();
mapper.enable(MapperFeature.USE_WRAPPER_NAME_AS_PROPERTY_NAME);
mapper.setAnnotationIntrospector(AnnotationIntrospector.pair(new JacksonAnnotationIntrospector(),
new JaxbAnnotationIntrospector(mapper.getTypeFactory())));
// Don't close the output stream
mapper.configure(JsonGenerator.Feature.AUTO_CLOSE_TARGET, false);
// Don't include NULL properties.
mapper.setSerializationInclusion(JsonInclude.Include.NON_NULL);
}
public JacksonContextResolver() {
mapper = new ObjectMapper();
mapper.enable(MapperFeature.USE_WRAPPER_NAME_AS_PROPERTY_NAME);
mapper.setAnnotationIntrospector(AnnotationIntrospector.pair(new JacksonAnnotationIntrospector(),
new JaxbAnnotationIntrospector(mapper.getTypeFactory())));
mapper.setSerializationInclusion(Include.NON_NULL);
}
public static ObjectMapper buildMapper() {
final ObjectMapper mapper = new ObjectMapper();
mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
mapper.setSerializationInclusion(JsonInclude.Include.NON_NULL);
final AnnotationIntrospector pair = AnnotationIntrospector.pair(
new JaxbAnnotationIntrospector(TypeFactory.defaultInstance()), new JacksonAnnotationIntrospector());
mapper.setAnnotationIntrospector(pair);
mapper.enable(MapperFeature.USE_ANNOTATIONS);
return mapper;
}
@VisibleForTesting
static ObjectMapper createConjureParserObjectMapper() {
ObjectMapper mapper = new ObjectMapper(new YAMLFactory())
.registerModule(new Jdk8Module())
.setAnnotationIntrospector(AnnotationIntrospector.pair(
new KebabCaseEnforcingAnnotationInspector(), // needs to come first.
new JacksonAnnotationIntrospector()));
mapper.enable(JsonParser.Feature.STRICT_DUPLICATE_DETECTION);
return mapper;
}
private static ObjectMapper createDefaultMapper() {
AnnotationIntrospector jacksonIntrospector = new JacksonAnnotationIntrospector();
ObjectMapper result = new ObjectMapper();
result.configure(SerializationFeature.INDENT_OUTPUT, true);
result.configure(SerializationFeature.FAIL_ON_EMPTY_BEANS, false);
result.getDeserializationConfig().withInsertedAnnotationIntrospector(jacksonIntrospector);
result.getSerializationConfig().withInsertedAnnotationIntrospector(jacksonIntrospector);
return result;
}
private static AnnotatedClass buildOldAnnotatedClass(Method method, Class<?> declaringClass,
SerializationConfig serializationConfig)
throws InvocationTargetException, IllegalAccessException {
boolean useAnnotations = serializationConfig.isAnnotationProcessingEnabled();
AnnotationIntrospector aintr = useAnnotations ? serializationConfig.getAnnotationIntrospector() : null;
return (AnnotatedClass) method.invoke(null, declaringClass, aintr, serializationConfig);
}
@Override
public Collection<NamedType> collectAndResolveSubtypesByTypeId(MapperConfig<?> config,
AnnotatedMember property, JavaType baseType)
{
final AnnotationIntrospector ai = config.getAnnotationIntrospector();
Class<?> rawBase = baseType.getRawClass();
// Need to keep track of classes that have been handled already
Set<Class<?>> typesHandled = new HashSet<Class<?>>();
Map<String,NamedType> byName = new LinkedHashMap<String,NamedType>();
// start with lowest-precedence, which is from type hierarchy
NamedType rootType = new NamedType(rawBase, null);
AnnotatedClass ac = AnnotatedClassResolver.resolveWithoutSuperTypes(config,
rawBase);
_collectAndResolveByTypeId(ac, rootType, config, typesHandled, byName);
// then with definitions from property
if (property != null) {
Collection<NamedType> st = ai.findSubtypes(property);
if (st != null) {
for (NamedType nt : st) {
ac = AnnotatedClassResolver.resolveWithoutSuperTypes(config, nt.getType());
_collectAndResolveByTypeId(ac, nt, config, typesHandled, byName);
}
}
}
// and finally explicit type registrations (highest precedence)
if (_registeredSubtypes != null) {
for (NamedType subtype : _registeredSubtypes) {
// is it a subtype of root type?
if (rawBase.isAssignableFrom(subtype.getType())) { // yes
AnnotatedClass curr = AnnotatedClassResolver.resolveWithoutSuperTypes(config,
subtype.getType());
_collectAndResolveByTypeId(curr, subtype, config, typesHandled, byName);
}
}
}
return _combineNamedAndUnnamed(rawBase, typesHandled, byName);
}
AnnotatedFieldCollector(AnnotationIntrospector intr,
TypeFactory types, MixInResolver mixins)
{
super(intr);
_typeFactory = types;
_mixInResolver = (intr == null) ? null : mixins;
}
public static List<AnnotatedField> collectFields(AnnotationIntrospector intr,
TypeResolutionContext tc,
MixInResolver mixins, TypeFactory types,
JavaType type)
{
return new AnnotatedFieldCollector(intr, types, mixins).collect(tc, type);
}
/**
* Constructor will not do any initializations, to allow for
* configuring instances differently depending on use cases
*
* @param type Fully resolved type; may be `null`, but ONLY if no member fields or
* methods are to be accessed
* @param rawType Type-erased class; pass if no `type` needed or available
*/
AnnotatedClass(JavaType type, Class<?> rawType, List<JavaType> superTypes,
Class<?> primaryMixIn, Annotations classAnnotations, TypeBindings bindings,
AnnotationIntrospector aintr, MixInResolver mir, TypeFactory tf)
{
_type = type;
_class = rawType;
_superTypes = superTypes;
_primaryMixIn = primaryMixIn;
_classAnnotations = classAnnotations;
_bindings = bindings;
_annotationIntrospector = aintr;
_mixInResolver = mir;
_typeFactory = tf;
}
@Override
@Deprecated
public final JsonFormat.Value findFormatOverrides(AnnotationIntrospector intr) {
JsonFormat.Value f = null;
if (intr != null) {
AnnotatedMember member = getMember();
if (member != null) {
f = intr.findFormat(member);
}
}
if (f == null) {
f = EMPTY_FORMAT;
}
return f;
}
protected POJOPropertiesCollector collectPropertiesWithBuilder(MapperConfig<?> config,
JavaType type, MixInResolver r, boolean forSerialization)
{
AnnotatedClass ac = _resolveAnnotatedClass(config, type, r);
AnnotationIntrospector ai = config.isAnnotationProcessingEnabled() ? config.getAnnotationIntrospector() : null;
JsonPOJOBuilder.Value builderConfig = (ai == null) ? null : ai.findPOJOBuilderConfig(ac);
String mutatorPrefix = (builderConfig == null) ? JsonPOJOBuilder.DEFAULT_WITH_PREFIX : builderConfig.withPrefix;
return constructPropertyCollector(config, ac, type, forSerialization, mutatorPrefix);
}
public static Creators collectCreators(AnnotationIntrospector intr,
TypeResolutionContext tc,
JavaType type, Class<?> primaryMixIn)
{
// Constructor also always members of resolved class, parent == resolution context
return new AnnotatedCreatorCollector(intr, tc)
.collect(type, primaryMixIn);
}
public static AnnotatedMethodMap collectMethods(AnnotationIntrospector intr,
TypeResolutionContext tc,
MixInResolver mixins, TypeFactory types,
JavaType type, List<JavaType> superTypes, Class<?> primaryMixIn)
{
// Constructor also always members of resolved class, parent == resolution context
return new AnnotatedMethodCollector(intr, mixins)
.collect(types, tc, type, superTypes, primaryMixIn);
}
protected CreatorCandidate(AnnotationIntrospector intr,
AnnotatedWithParams ct, Param[] params, int count) {
_intr = intr;
_creator = ct;
_params = params;
_paramCount = count;
}
public static CreatorCandidate construct(AnnotationIntrospector intr,
AnnotatedWithParams creator, BeanPropertyDefinition[] propDefs)
{
final int pcount = creator.getParameterCount();
Param[] params = new Param[pcount];
for (int i = 0; i < pcount; ++i) {
AnnotatedParameter annParam = creator.getParameter(i);
JacksonInject.Value injectId = intr.findInjectableValue(annParam);
params[i] = new Param(annParam, (propDefs == null) ? null : propDefs[i], injectId);
}
return new CreatorCandidate(intr, creator, params, pcount);
}
/**
* Factory method for constructing resolver that maps from Enum.toString() into
* Enum value
*
* @since 2.8
*/
public static EnumResolver constructUsingToString(Class<Enum<?>> enumCls,
AnnotationIntrospector ai)
{
Enum<?>[] enumValues = enumCls.getEnumConstants();
HashMap<String, Enum<?>> map = new HashMap<String, Enum<?>>();
// from last to first, so that in case of duplicate values, first wins
for (int i = enumValues.length; --i >= 0; ) {
Enum<?> e = enumValues[i];
map.put(e.toString(), e);
}
Enum<?> defaultEnum = (ai == null) ? null : ai.findDefaultEnumValue(enumCls);
return new EnumResolver(enumCls, enumValues, map, defaultEnum);
}
/**
* This method is needed because of the dynamic nature of constructing Enum
* resolvers.
*/
@SuppressWarnings({ "unchecked" })
public static EnumResolver constructUnsafe(Class<?> rawEnumCls, AnnotationIntrospector ai)
{
/* This is oh so wrong... but at least ugliness is mostly hidden in just
* this one place.
*/
Class<Enum<?>> enumCls = (Class<Enum<?>>) rawEnumCls;
return constructFor(enumCls, ai);
}
/**
* Method that needs to be used instead of {@link #constructUsingToString}
* if static type of enum is not known.
*
* @since 2.8
*/
@SuppressWarnings({ "unchecked" })
public static EnumResolver constructUnsafeUsingToString(Class<?> rawEnumCls,
AnnotationIntrospector ai)
{
// oh so wrong... not much that can be done tho
Class<Enum<?>> enumCls = (Class<Enum<?>>) rawEnumCls;
return constructUsingToString(enumCls, ai);
}
/**
* Method used when actual String serialization is indicated using @JsonValue
* on a method.
*
* @since 2.9
*/
@SuppressWarnings({ "unchecked" })
public static EnumResolver constructUnsafeUsingMethod(Class<?> rawEnumCls,
AnnotatedMember accessor,
AnnotationIntrospector ai)
{
// wrong as ever but:
Class<Enum<?>> enumCls = (Class<Enum<?>>) rawEnumCls;
return constructUsingMethod(enumCls, accessor, ai);
}
/**
* Returns the graph for json.
*
* @param <T> the generic type
* @param json the json
* @param graphClass the graph class
* @return the graph for json
* @throws Exception the exception
*/
public static <T> T getGraphForJson(String json, Class<T> graphClass)
throws Exception {
InputStream in =
new ByteArrayInputStream(json.getBytes(StandardCharsets.UTF_8));
ObjectMapper mapper = new ObjectMapper();
AnnotationIntrospector introspector =
new JaxbAnnotationIntrospector(mapper.getTypeFactory());
mapper.setAnnotationIntrospector(introspector);
return mapper.readValue(in, graphClass);
}
/**
* Returns the json for graph.
*
* @param object the object
* @return the json for graph
* @throws Exception the exception
*/
public static String getJsonForGraph(Object object) throws Exception {
ObjectMapper mapper = new ObjectMapper();
AnnotationIntrospector introspector =
new JaxbAnnotationIntrospector(mapper.getTypeFactory());
mapper.setAnnotationIntrospector(introspector);
return mapper.writeValueAsString(object);
}