zoukankan      html  css  js  c++  java
  • 从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());

  • 相关阅读:
    最优二叉查找树
    最长公共子序列问题
    最大子段和问题
    01背包问题
    浅析LRU(K-V)缓存
    LeetCode——LRU Cache
    LeetCode——Gas Station
    LeetCode——Jump Game II
    LeetCode——Jump Game
    LeetCode——Implement Trie (Prefix Tree)
  • 原文地址:https://www.cnblogs.com/lightarc/p/jsontestq.html
Copyright © 2011-2022 走看看