配置spring boot请求的入参和出参json数据格式

请求入参数据格式配置,以日期格式为例:

编写日期编辑器类:

  

import first.zxz.tools.DateUtil;

import java.beans.PropertyEditorSupport;

/**
 * 日期编辑器
 *
 * @author zhangxz
 * @date 2019-11-12 20:01
 */

public class DateEditor extends PropertyEditorSupport {
    /**
     * 是否将null转换为空字符串
     */
    private final boolean nullAsEmpty;

    public DateEditor() {
        this(true);
    }

    public DateEditor(boolean nullAsEmpty) {
        this.nullAsEmpty = nullAsEmpty;
    }

    @Override
    public void setAsText(String text) {
        if (text == null) {
            if (nullAsEmpty) {
                setValue("");
            } else {
                setValue(null);
            }
        } else {
            setValue(DateUtil.parse(text));
        }
    }

}

其中用到的日期工具类如下:

public class DateUtil {

    private static final String DATE_FORMAT_1 = "yyyy-MM-dd";
    private static final String DATE_FORMAT_2 = "yyyy/MM/dd";
    private static final String DATE_FORMAT_3 = "yyyyMMdd";
    private static final String DATE_TIME_FORMAT_1 = DATE_FORMAT_1 + " HH:mm:ss";
    private static final String DATE_TIME_FORMAT_2 = DATE_FORMAT_2 + " HH:mm:ss";
    private static final String DATE_TIME_FORMAT_3 = DATE_FORMAT_3 + "HHmmss";

    //key为正则表达式,value为对应的日期格式
    private static final HashMap<String, String> DATE_REGEX_FORMATTER_MAP = new HashMap<>();

    static {
        DATE_REGEX_FORMATTER_MAP.put(DateRegexConst.DATE_1, DATE_FORMAT_1);
        DATE_REGEX_FORMATTER_MAP.put(DateRegexConst.DATE_2, DATE_FORMAT_2);
        DATE_REGEX_FORMATTER_MAP.put(DateRegexConst.DATE_3, DATE_FORMAT_3);
        DATE_REGEX_FORMATTER_MAP.put(DateRegexConst.DATE_TIME_1, DATE_TIME_FORMAT_1);
        DATE_REGEX_FORMATTER_MAP.put(DateRegexConst.DATE_TIME_2, DATE_TIME_FORMAT_2);
        DATE_REGEX_FORMATTER_MAP.put(DateRegexConst.DATE_TIME_3, DATE_TIME_FORMAT_3);
    }

    //提示语:所有可用的日期格式
    public static final String ALL_USABLE_DATE_FORMATS = DATE_REGEX_FORMATTER_MAP.values().toString() + ",以及时间戳;";

    /**
     * 根据输入的字符串,进行格式化,并输入日期数据
     * 注意:格式化之前,会进行null和空字符串过滤;格式化时,会去除字符串两端的空字符串
     *
     * @param formattedDateStr 日期字符串数据
     * @return java.util.Date
     * @author Zxz
     * @date 2019/11/6 15:07
     **/
    public static Date parse(String formattedDateStr) {
        if (formattedDateStr == null || formattedDateStr.trim().length() <= 0) {
            throw new StringEmptyException();
        }

        for (Map.Entry<String, String> entry : DATE_REGEX_FORMATTER_MAP.entrySet()) {
            if (formattedDateStr.trim().matches(entry.getKey())) {
                SimpleDateFormat simpleDateFormat = new SimpleDateFormat(entry.getValue());
                try {
                    return simpleDateFormat.parse(formattedDateStr.trim());
                } catch (ParseException e) {
                    e.printStackTrace();
                    throw new DateFormatException();
                }
            }
        }

        try {
            Long aLong = Long.valueOf(formattedDateStr);
            return new Date(aLong);
        } catch (NumberFormatException e) {
            //格式不匹配
            throw new DateFormatException();
        }

    }
}

把编辑器加入web的绑定初始化配置:

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.format.support.FormattingConversionService;
import org.springframework.validation.Validator;
import org.springframework.web.bind.support.ConfigurableWebBindingInitializer;
import simple.proj.zxz.play.config.editor.DateEditor;

import java.util.Date;

/**
 * 配置请求 bean数据接收格式,例如date格式
 *
 * @author zhangxz
 * @date 2019-11-12 19:56
 */

@Configuration
public class WebBindingInitializerConfig {

    /**
     * 配置请求入参数据格式,参考{@link simple.proj.zxz.play.config.editor.DateEditor}
     *
     * @param mvcConversionService mvc版本业务
     * @param mvcValidator         mvc校验器
     * @return org.springframework.web.bind.support.ConfigurableWebBindingInitializer
     * @author zhangxz
     * @date 2019/11/13 10:40
     */
    @Bean
    public ConfigurableWebBindingInitializer configurableWebBindingInitializer(FormattingConversionService mvcConversionService, Validator mvcValidator) {
        ConfigurableWebBindingInitializer initializer = new ConfigurableWebBindingInitializer();
        initializer.setConversionService(mvcConversionService);
        initializer.setValidator(mvcValidator);

        initializer.setPropertyEditorRegistrar(propertyEditorRegistry -> {
            //PropertyEditor 非线程安全
            propertyEditorRegistry.registerCustomEditor(Date.class, new DateEditor());
        });
        return initializer;
    }

}

入参的日期数据格式配置完成,可以接收的日期格式在日期工具类可以看到,有以下几种:yyyy-mm-dd,时间戳,yyyy-mm-dd hh:mm:ss等。

请求出参格式配置,包括空字符串,空数组,以及日期格式化输出

编写空字符串序列器:

  

import com.fasterxml.jackson.core.JsonGenerator;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.JsonSerializer;
import com.fasterxml.jackson.databind.SerializerProvider;

import java.io.IOException;

/**
 * 空字符串序列器
 *
 * @author zhangxz
 * @date 2019-11-12 22:05
 */
public class NullStringSerializer extends JsonSerializer {

    @Override
    public void serialize(Object o, JsonGenerator jsonGenerator, SerializerProvider serializerProvider)
            throws IOException, JsonProcessingException {
        jsonGenerator.writeString("");
    }
}

编写空数组序列器

/**
 * 空数组或集合序列器
 *
 * @author zhangxz
 * @date 2019-11-12 22:04
 */

public class NullArraySerializer extends JsonSerializer {

    @Override
    public void serialize(Object value, JsonGenerator jgen, SerializerProvider provider) throws IOException, JsonProcessingException {
        jgen.writeStartArray();
        jgen.writeEndArray();
    }
}

编写日期序列器

import com.fasterxml.jackson.core.JsonGenerator;
import com.fasterxml.jackson.databind.JsonSerializer;
import com.fasterxml.jackson.databind.SerializerProvider;

import java.io.IOException;
import java.util.Date;

/**
 * 日期序列器
 *
 * @author zhangxz
 * @date 2019-11-12 23:01
 */
public class DateSerializer extends JsonSerializer {

    /**
     * 日期序列化方法,返回时间戳格式
     *
     * @param o                  数值
     * @param jsonGenerator      json生成器
     * @param serializerProvider 序列器
     * @author zhangxz
     * @date 2019/11/13 10:41
     */
    @Override
    public void serialize(Object o, JsonGenerator jsonGenerator, SerializerProvider serializerProvider) throws IOException {
        jsonGenerator.writeNumber(((Date) o).getTime());
    }
}

编写总序列器

import com.fasterxml.jackson.databind.BeanDescription;
import com.fasterxml.jackson.databind.JsonSerializer;
import com.fasterxml.jackson.databind.SerializationConfig;
import com.fasterxml.jackson.databind.ser.BeanPropertyWriter;
import com.fasterxml.jackson.databind.ser.BeanSerializerModifier;

import java.util.Collection;
import java.util.Date;
import java.util.List;

/**
 * 总序列器
 *
 * @author zhangxz
 * @date 2019-11-12 22:07
 */

public class GeneralSerializer extends BeanSerializerModifier {

    //空数组
    private JsonSerializer _nullArraySerializer = new NullArraySerializer();
    //空字符串
    private JsonSerializer _nullStringSerializer = new NullStringSerializer();
    //日期类型
    private JsonSerializer dateSerializer = new DateSerializer();

    @Override
    public List<BeanPropertyWriter> changeProperties(SerializationConfig config, BeanDescription beanDesc,
                                                     List<BeanPropertyWriter> beanProperties) {
        for (BeanPropertyWriter beanProperty : beanProperties) {
            if (isArrayType(beanProperty)) {
                beanProperty.assignNullSerializer(this._nullArraySerializer);
            } else if (isStringType(beanProperty)) {
                beanProperty.assignNullSerializer(this._nullStringSerializer);
            } else if (isDateType(beanProperty)) {
                beanProperty.assignSerializer(this.dateSerializer);
            }
        }
        return beanProperties;
    }

    private boolean isStringType(BeanPropertyWriter writer) {
        Class clazz = writer.getType().getRawClass();
        return clazz == String.class;
    }

    private boolean isDateType(BeanPropertyWriter writer) {
        return Date.class == writer.getType().getRawClass();
    }

    private boolean isArrayType(BeanPropertyWriter writer) {
        Class clazz = writer.getType().getRawClass();
        return clazz.isArray() || Collection.class.isAssignableFrom(clazz);
    }


}

把总序列器加入web配置中:

import com.fasterxml.jackson.databind.ObjectMapper;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.converter.json.MappingJackson2HttpMessageConverter;
import simple.proj.zxz.play.config.serializer.GeneralSerializer;

/**
 * @description: 配置jackson 序列器
 * @author: zhangxz
 * @create: 2019-11-12 22:02
 */


@Configuration
public class JacksonConfig {

    /**
     * 出参数据格式配置,参考类 {@link simple.proj.zxz.play.config.serializer.GeneralSerializer}
     *
     * @return org.springframework.http.converter.json.MappingJackson2HttpMessageConverter
     * @author zhangxz
     * @date 2019/11/13 10:34
     */
    @Bean
    public MappingJackson2HttpMessageConverter mappingJacksonHttpMessageConverter() {

        final MappingJackson2HttpMessageConverter converter = new MappingJackson2HttpMessageConverter();
        ObjectMapper mapper = converter.getObjectMapper();
        mapper.setSerializerFactory(mapper.getSerializerFactory().withSerializerModifier(new GeneralSerializer()));

        return converter;
    }

}

请求出参配置完成,出参格式如下:null的字符串输出为空字符串,null的数组输出为空数组,date数据格式输出为时间戳。

参考博客:

  https://blog.csdn.net/qq_36356627/article/details/82953011

  https://blog.csdn.net/qq_36804701/article/details/81116119

  https://blog.csdn.net/Michean/article/details/90901450

原文地址:https://www.cnblogs.com/zhangxuezhi/p/11847773.html