介绍

在使用Spring Boot的RestController注解的时候,会自动的帮我们将对象转化成对应json对象返回,但是因为对象的一些特殊的类型导致默认的序列化器不生效,比如Long、Oracle的Clob类型等。因为Spring Bott2用的是Jackson的ObjectMapper进行序列化,我们需要自己重新定义序列化器。

解决

通过自定义一个类来实现自定义序列化器。

package com.benzhu.springcloud.config;

import com.fasterxml.jackson.core.JsonGenerator;
import com.fasterxml.jackson.databind.*;
import com.fasterxml.jackson.databind.module.SimpleModule;
import oracle.sql.CLOB;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Primary;
import org.springframework.http.converter.json.Jackson2ObjectMapperBuilder;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.Reader;
import java.text.SimpleDateFormat;

/**
 * @description: 自定义序列化器
 **/
@Configuration
public class JacksonConfig {
    @Bean
    @Primary
    @ConditionalOnMissingBean(ObjectMapper.class)
    public ObjectMapper jacksonObjectMapper(Jackson2ObjectMapperBuilder builder) {
        ObjectMapper objectMapper = builder.createXmlMapper(false).build();
        //开启缩放排列输出
        objectMapper.enable(SerializationFeature.INDENT_OUTPUT);
        //反序列化的时候 个别请求参数不对应 也正常解析为对象
        objectMapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
        //定义时间的序列化方式
        objectMapper.setDateFormat(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"));
        //定义为空的时候序列化为空字符串
        objectMapper.getSerializerProvider().setNullValueSerializer(new JsonSerializer() {
            @Override
            public void serialize(Object o, JsonGenerator jsonGenerator, SerializerProvider serializerProvider) throws IOException {
                jsonGenerator.writeString("");
            }
        });
        //添加自定义的CLOB序列化构造类
        SimpleModule module = new SimpleModule();
        module.addSerializer(CLOB.class, new OracleClobSerializer());
        objectMapper.registerModule(module);
        return objectMapper;
    }

    /**
     * 功能描述:
     * (自定义CLOB的序列器)
     *
     */
    public class OracleClobSerializer extends JsonSerializer<CLOB>{

        @Override
        public void serialize(CLOB clob, JsonGenerator jsonGenerator, SerializerProvider serializerProvider) throws IOException {
            try {
                if(clob == null){
                    jsonGenerator.writeString("");
                }else{
                    Reader is = clob.getCharacterStream();
                    BufferedReader br = new BufferedReader(is);
                    String s = br.readLine();
                    StringBuffer sb = new StringBuffer();
                    while(s != null){
                        sb.append(s);
                        s = br.readLine();
                    }
                    jsonGenerator.writeString(sb.toString());
                }
            } catch (Exception e) {
                e.printStackTrace();
                jsonGenerator.writeString("");
            }
        }
    }
}

其他序列化参数

//这个特性,决定了解析器是否将自动关闭那些不属于parser自己的输入源。
// 如果禁止,则调用应用不得不分别去关闭那些被用来创建parser的基础输入流InputStream和reader;
//默认是true
objectMapper.configure(JsonParser.Feature.AUTO_CLOSE_SOURCE, true);
//是否允许解析使用Java/C++ 样式的注释(包括'/'+'*' 和'//' 变量)
objectMapper.configure(JsonParser.Feature.ALLOW_COMMENTS, true);

//设置为true时,属性名称不带双引号
objectMapper.configure(JsonGenerator.Feature.QUOTE_FIELD_NAMES, false);
//反序列化是是否允许属性名称不带双引号
objectMapper.configure(JsonParser.Feature.ALLOW_UNQUOTED_FIELD_NAMES, true);

//是否允许单引号来包住属性名称和字符串值
objectMapper.configure(JsonParser.Feature.ALLOW_SINGLE_QUOTES, true);

//是否允许JSON字符串包含非引号控制字符(值小于32的ASCII字符,包含制表符和换行符)
objectMapper.configure(JsonParser.Feature.ALLOW_UNQUOTED_CONTROL_CHARS, true);

//是否允许JSON整数以多个0开始
objectMapper.configure(JsonParser.Feature.ALLOW_NUMERIC_LEADING_ZEROS, true);

//null的属性不序列化
objectMapper.setSerializationInclusion(JsonInclude.Include.NON_NULL);

//按字母顺序排序属性,默认false
objectMapper.configure(MapperFeature.SORT_PROPERTIES_ALPHABETICALLY,true);

//是否以类名作为根元素,可以通过@JsonRootName来自定义根元素名称,默认false
objectMapper.configure(SerializationFeature.WRAP_ROOT_VALUE,true);

//是否缩放排列输出,默认false
objectMapper.configure(SerializationFeature.INDENT_OUTPUT,false);

//序列化Date日期时以timestamps输出,默认true
objectMapper.configure(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS,true);

//序列化枚举是否以toString()来输出,默认false,即默认以name()来输出
objectMapper.configure(SerializationFeature.WRITE_ENUMS_USING_TO_STRING, true);

//序列化枚举是否以ordinal()来输出,默认false
objectMapper.configure(SerializationFeature.WRITE_ENUMS_USING_INDEX,false);

//序列化单元素数组时不以数组来输出,默认false
objectMapper.configure(SerializationFeature.WRITE_ENUMS_USING_TO_STRING,true);

//序列化Map时对key进行排序操作,默认false
objectMapper.configure(SerializationFeature.ORDER_MAP_ENTRIES_BY_KEYS,true);

//序列化char[]时以json数组输出,默认false
objectMapper.configure(SerializationFeature.WRITE_CHAR_ARRAYS_AS_JSON_ARRAYS,true);

//序列化BigDecimal时是输出原始数字还是科学计数,默认false,即以toPlainString()科学计数方式来输出
objectMapper.configure(SerializationFeature.WRITE_BIGDECIMAL_AS_PLAIN,true);