protected JsonSerializer _createAndCacheUntypedSerializer(Class> rawType)
throws JsonMappingException
{
JavaType fullType = _config.constructType(rawType);
JsonSerializer ser;
try {
ser = _createUntypedSerializer(fullType); //创建序列化器
} catch (IllegalArgumentException iae) {
// We better only expose checked exceptions, since those
// are what caller is expected to handle
ser = null; // doesn't matter but compiler whines otherwise
reportMappingProblem(iae, ClassUtil.exceptionMessage(iae));
}
if (ser != null) {
// 21-Dec-2015, tatu: Best to cache for both raw and full-type key
_serializerCache.addAndResolveNonTypedSerializer(rawType, fullType, ser, this);
}
return ser;
}
@Override
@SuppressWarnings("unchecked")
public JsonSerializer createSerializer(SerializerProvider prov,
JavaType origType)
throws JsonMappingException
{
// Very first thing, let's check if there is explicit serializer annotation:
final SerializationConfig config = prov.getConfig();
BeanDescription beanDesc = config.introspect(origType);
//通过注解来创建序列化器
JsonSerializer> ser = findSerializerFromAnnotation(prov, beanDesc.getClassInfo());
if (ser != null) {
return (JsonSerializer) ser;
}
... 忽略其他
}
最终:
protected JsonSerializer findSerializerFromAnnotation(SerializerProvider prov,
Annotated a)
throws JsonMappingException
{
/**
prov使用的是之前构建的 SerializationConfig 类,其中包含了 我们自定义的 AnnotationIntrospector
getAnnotationIntrospector()可以获取到这个自定义的AnnotationIntrospector并调用其方法返回我们自定义的序列化器
*/
Object serDef = prov.getAnnotationIntrospector().findSerializer(a);
if (serDef == null) {
return null;
}
JsonSerializer ser = prov.serializerInstance(a, serDef);
// One more thing however: may need to also apply a converter:
return (JsonSerializer) findConvertingSerializer(prov, a, ser);
}
这样我们就能使用自定义注解+自定义的序列化器来实现字段的序列化。
反序列化
反序列化的过程和序列化的过程相似。
protected Object _readMapAndClose(JsonParser p0, JavaType valueType)
throws IOException
{
try (JsonParser p = p0) {
Object result;
JsonToken t = _initForReading(p, valueType);
/**这里构建了 使用 _deserializationConfig的 DeserializationConfig
而_deserializationConfig中包含了我们自定义的注解解释器
*/
final DeserializationConfig cfg = getDeserializationConfig();
final DeserializationContext ctxt = createDeserializationContext(p, cfg);
if (t == JsonToken.VALUE_NULL) {
// Ask JsonDeserializer what 'null value' to use:
result = _findRootDeserializer(ctxt, valueType).getNullValue(ctxt);
} else if (t == JsonToken.END_ARRAY || t == JsonToken.END_OBJECT) {
result = null;
} else {
//这里开始反序列化数据
JsonDeserializer deser = _findRootDeserializer(ctxt, valueType);
if (cfg.useRootWrapping()) {
result = _unwrapAndDeserialize(p, ctxt, cfg, valueType, deser);
} else {
result = deser.deserialize(p, ctxt);
}
ctxt.checkUnresolvedObjectId();
}
if (cfg.isEnabled(DeserializationFeature.FAIL_ON_TRAILING_TOKENS)) {
_verifyNoTrailingTokens(p, ctxt, valueType);
}
return result;
}
}
最终也会执行到创建反序列化器的方法(DeserializationContext)中
protected JsonDeserializer _createDeserializer(DeserializationContext ctxt,
DeserializerFactory factory, JavaType type)
throws JsonMappingException
{
final DeserializationConfig config = ctxt.getConfig();
// First things first: do we need to use abstract type mapping?
if (type.isAbstract() || type.isMapLikeType() || type.isCollectionLikeType()) {
type = factory.mapAbstractType(config, type);
}
BeanDescription beanDesc = config.introspect(type);
// Then: does type define explicit deserializer to use, with annotation(s)?
/**
这里通过获取注解序列化器
*/
JsonDeserializer deser = findDeserializerFromAnnotation(ctxt,
beanDesc.getClassInfo());
if (deser != null) {
return deser;
}
//... 忽略其他
}
创建注解序列化器的方法:
protected JsonDeserializer findDeserializerFromAnnotation(DeserializationContext ctxt,
Annotated ann)
throws JsonMappingException
{
/**
ctxt中包含了我们自定的注解解释器 - _deserializationConfig。
*/
Object deserDef = ctxt.getAnnotationIntrospector().findDeserializer(ann);
if (deserDef == null) {
return null;
}
JsonDeserializer deser = ctxt.deserializerInstance(ann, deserDef);
// One more thing however: may need to also apply a converter:
return findConvertingDeserializer(ctxt, ann, deser);
}
这样就能得到我们自定义的注解解释器,并在注解解释器中返回我们自定义的字段序列化和反序列实现。
具体实现
首先我们需要自定义一个注解,以及一个包含了注解的实体类。
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
@Retention(RetentionPolicy.RUNTIME)
public @interface TestAnnotation {
}
@Data
public class TestBean {
private String name;
private Integer age;
@TestAnnotation
private String serise;
}
/**
* Method called to check whether given property is marked to
* be ignored. This is used to determine whether to ignore
* properties, on per-property basis, usually combining
* annotations from multiple accessors (getters, setters, fields,
* constructor parameters).
*/
public boolean hasIgnoreMarker(AnnotatedMember m) { return false; }
/**
* Method that can be called to check whether this member has
* an annotation that suggests whether value for matching property
* is required or not.
*/
public Boolean hasRequiredMarker(AnnotatedMember m) { return null; }
1. 创建一个maven项目
2. 创建com.CoberturaStart.java
package com;
public class CoberturaStart {
public void helloEveryone(){
System.out.println("=================================================
我并不知道出现这个问题的实际原理,只是通过其他朋友的博客,文章得知的一个解决方案,目前先记录一个解决方法,未来要是真了解以后,还会继续补全.
在mysql5中有一个safe update mode,这个模式让sql操作更加安全,据说要求有where条件,防止全表更新操作.如果必须要进行全表操作,我们可以执行
SET
public class DeleteSpecificChars {
/**
* Q 63 在字符串中删除特定的字符
* 输入两个字符串,从第一字符串中删除第二个字符串中所有的字符。
* 例如,输入”They are students.”和”aeiou”,则删除之后的第一个字符串变成”Thy r stdnts.”
*/
public static voi
File descriptors are represented by the C int type. Not using a special type is often considered odd, but is, historically, the Unix way. Each Linux process has a maximum number of files th