从json-lib转成jackson的遇到的问题
从json-lib转成jackson的遇到的问题
问题一:json 字符串,再经过Jackson序列化之后就变成原生字符串了。而json-lib经过再序列化之后,还是json格式的串。
针对这种情况,可以写一个Serializer类,遇到json串的时候就当作原生字符串写入即可。
<<JsonStringSerializer>>
/**
* 序列化时,对Json格式的字符串做特殊处理:不用引号括起来
* @author
*
*/
public class JsonStringSerializer extends JsonSerializer<Object> {
@Override
public void serialize(Object value, JsonGenerator jgen, SerializerProvider provider) throws IOException {
if (value == null) {
jgen.writeNull();
} else {
if (value instanceof String) {
String newValue = ((String) value).trim();
// 只对Json格式的字符串做处理
if (newValue.startsWith("{") || newValue.startsWith("[")) {
jgen.writeRawValue((String) value);
} else {
jgen.writeObject(value);
}
} else {
jgen.writeObject(value);
}
}
}
}
问题二、jackson和json-lib对null值的处理大不相同。对于值为null的字符串类型的字段,jackson输出null,而json-lib输出空字符串。对于List类型,json-lib输出空列表[],而jackson还是输出null。
如果是从json-lib移植到jackson,为了兼容老代码,可以写一个SerializerProvider,遇到null值输出空字符串等。
<<NullToEmptyStringProvider>>
/**
* Customize the DefaultSerializerProvider so that when it is looking for a
* NullSerializer it will use one that is class sensitive, writing strings as ""
* and everything else using the default value.
*
* @author
*/
public class NullToEmptyStringProvider extends DefaultSerializerProvider {
private static final long serialVersionUID = -1L;
// A couple of constructors and factory methods to keep the compiler happy
public NullToEmptyStringProvider() {
super();
}
public NullToEmptyStringProvider(NullToEmptyStringProvider provider, SerializationConfig config,
SerializerFactory jsf) {
super(provider, config, jsf);
}
@Override
public NullToEmptyStringProvider createInstance(SerializationConfig config, SerializerFactory jsf) {
return new NullToEmptyStringProvider(this, config, jsf);
}
@Override
public JsonSerializer<Object> findNullValueSerializer(BeanProperty property) throws JsonMappingException {
if (property.getType().getRawClass().equals(String.class)) {
return EmptyStringSerializer.INSTANCE;
} else if ((property.getType().isArrayType() || property.getType().isCollectionLikeType())
&& !property.getType().isMapLikeType()) {
return EmptyListSerializer.INSTANCE;
} else if (property.getType().getRawClass().equals(Long.class)
|| property.getType().getRawClass().equals(Short.class)
|| property.getType().getRawClass().equals(Integer.class)
|| property.getType().getRawClass().equals(Double.class)
|| property.getType().getRawClass().equals(Float.class)
|| property.getType().getRawClass().equals(BigDecimal.class)) {
return EmptyNumberSerializer.INSTANCE;
} else {
return super.findNullValueSerializer(property);
}
}
}
/**
* Output null of String to empty string.
*
* @author
*
*/
class EmptyStringSerializer extends JsonSerializer<Object> {
public static final JsonSerializer<Object> INSTANCE = new EmptyStringSerializer();
private EmptyStringSerializer() {
}
// Since we know we only get to this seralizer in the case where the value
// is null and the type is String, we can
// do our handling without any additional logic and write that empty string
// we are so desperately wanting.
@Override
public void serialize(Object o, JsonGenerator jsonGenerator, SerializerProvider serializerProvider)
throws IOException {
jsonGenerator.writeString("");
}
}
/**
* For null list
* @author
*
*/
class EmptyListSerializer extends JsonSerializer<Object> {
public static final JsonSerializer<Object> INSTANCE = new EmptyListSerializer();
private EmptyListSerializer() {
}
// Since we know we only get to this seralizer in the case where the value
// is null and the type is String, we can
// do our handling without any additional logic and write that empty string
// we are so desperately wanting.
@Override
public void serialize(Object o, JsonGenerator jsonGenerator, SerializerProvider serializerProvider)
throws IOException {
jsonGenerator.writeStartArray();
jsonGenerator.writeEndArray();
}
}
/**
* For null Number, such as Integer, Long, Short ....
* @author
*
*/
class EmptyNumberSerializer extends JsonSerializer<Object> {
public static final JsonSerializer<Object> INSTANCE = new EmptyNumberSerializer();
private EmptyNumberSerializer() {
}
// Since we know we only get to this seralizer in the case where the value
// is null and the type is String, we can
// do our handling without any additional logic and write that empty string
// we are so desperately wanting.
@Override
public void serialize(Object o, JsonGenerator jsonGenerator, SerializerProvider serializerProvider)
throws IOException {
jsonGenerator.writeNumber(0);
}
}
最后,需要把这个provider配置到jackson的mapper实例中。
jsonMapper.setSerializerProvider(new NullToEmptyStringProvider());