使用fastjson处理请求/响应中的时间字段(springboot)

385 阅读1分钟

一. get请求时间参数处理

package cors.test.config;

import org.apache.commons.lang3.time.DateUtils;
import org.apache.commons.lang3.time.DateFormatUtils;
import org.springframework.web.bind.WebDataBinder;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.InitBinder;

import java.beans.PropertyEditorSupport;
import java.text.ParseException;
import java.util.Date;
import java.util.Locale;

/**
 * get请求时间处理
 */
@ControllerAdvice
public class FastJsonControllerAdvice {
    @InitBinder
    public void initBinder(WebDataBinder binder) {
        binder.registerCustomEditor(Date.class, new DateEditor());
    }

    private class DateEditor extends PropertyEditorSupport {
        @Override
        public void setAsText(String text) throws IllegalArgumentException {
            Date date = null;
            try {
                //请求 yyyy-MM-dd HH:mm:ss 、 yyyy-MM-dd 两种时间格式
                date = DateUtils.parseDate(text, (Locale) null,
                        "yyyy-MM-dd HH:mm:ss",
                        "yyyy-MM-dd");
            } catch (ParseException e) {
                e.printStackTrace();
            }
            setValue(date);
        }

        @Override
        public String getAsText() {
            Object value = getValue();
            if(value == null || !(value instanceof Date))
                return null;
            else {
                //返回格式统一为 yyyy-MM-dd HH:mm:ss
                return DateFormatUtils.format((Date) getValue(), "yyyy-MM-dd HH:mm:ss"); 
            }
        }
    }
}

二. post请求body处理

package cors.test.config;

import org.apache.commons.lang3.time.DateUtils;
import org.apache.commons.lang3.StringUtils;
import com.alibaba.fastjson.parser.DefaultJSONParser;
import com.alibaba.fastjson.parser.deserializer.TimeDeserializer;
import com.alibaba.fastjson.serializer.JSONSerializer;
import com.alibaba.fastjson.serializer.SerializerFeature;
import com.alibaba.fastjson.serializer.SimpleDateFormatSerializer;
import com.alibaba.fastjson.support.config.FastJsonConfig;
import com.alibaba.fastjson.support.spring.FastJsonHttpMessageConverter;
import org.apache.commons.lang3.time.DateFormatUtils;
import org.springframework.boot.autoconfigure.http.HttpMessageConverters;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.MediaType;
import org.springframework.http.converter.HttpMessageConverter;

import java.io.IOException;
import java.lang.reflect.Type;
import java.nio.charset.StandardCharsets;
import java.text.ParseException;
import java.util.*;

/**
 * post请求body处理
 */
@Configuration
public class FastJsonHttpMessageConverterConfigurer  {

    @Bean
    public HttpMessageConverters fastJsonConfigure() {
        FastJsonHttpMessageConverter fastJsonHttpMessageConverter = new FastJsonHttpMessageConverter();
        //需要处理的 Content-Type 类型
        MediaType[] jsonMediaTypes = new MediaType[] { new MediaType(MediaType.TEXT_PLAIN, StandardCharsets.UTF_8), MediaType.APPLICATION_JSON };
        List<MediaType> supportedMediaTypes = new ArrayList<>(fastJsonHttpMessageConverter.getSupportedMediaTypes());
        Collections.addAll(supportedMediaTypes, jsonMediaTypes);
        fastJsonHttpMessageConverter.setSupportedMediaTypes(supportedMediaTypes);
        //默认字符集
        fastJsonHttpMessageConverter.setDefaultCharset(StandardCharsets.UTF_8);

        FastJsonConfig fastJsonConfig = new FastJsonConfig();
        fastJsonConfig.setSerializerFeatures(
                SerializerFeature.WriteMapNullValue,
                SerializerFeature.DisableCircularReferenceDetect
        );
        //时间类型的处理,格式与get请求一致
        fastJsonConfig.getSerializeConfig().put(Date.class, new DateFormatSerializer());
        fastJsonConfig.getParserConfig().putDeserializer(Date.class, new DateFormatDeserializer());
        fastJsonHttpMessageConverter.setFastJsonConfig(fastJsonConfig);

        List<HttpMessageConverter<?>> converters = new ArrayList<>(new HttpMessageConverters().getConverters());
        //去掉原来的json处理
        converters.removeIf(x -> {
            for (MediaType jsonMediaType : jsonMediaTypes) {
                if(x.getSupportedMediaTypes().contains(jsonMediaType))
                    return true;
            }
            return false;
        });
        converters.add(fastJsonHttpMessageConverter);
        return new HttpMessageConverters(false, converters);
    }
    
    //响应处理
    public static class DateFormatSerializer extends SimpleDateFormatSerializer {
        private static TimeZone TIME_ZONE = TimeZone.getTimeZone("Asia/Shanghai");

        public DateFormatSerializer() {
            super("yyyy-MM-dd HH:mm:ss");
        }

        @Override
        public void write(JSONSerializer serializer, Object object, Object fieldName, Type fieldType, int features) throws IOException {
            if(object == null)
                super.write(serializer, object, fieldName, fieldType, features);
            else {
                TimeZone timeZone = (TimeZone) TIME_ZONE.clone();
                serializer.out.writeString(DateFormatUtils.format((Date) object, "yyyy-MM-dd HH:mm:ss", timeZone, null));
            }
        }
    }
    
    //请求处理
    public static class DateFormatDeserializer extends TimeDeserializer {

        @Override
        public <T> T deserialze(DefaultJSONParser parser, Type clazz, Object fieldName) {
            Object val = parser.parse();
            if (val == null){
                return null;
            }
            if(val instanceof String) {
                if (StringUtils.isEmpty((String) val)) return null;
                try {
                    return (T) DateUtils.parseDate((String) val, (Locale) null,
                            "yyyy-MM-dd HH:mm:ss",
                            "yyyy-MM-dd");
                } catch (ParseException e) {
                    return null;
                }
            } else {
                return super.deserialze(parser, clazz, fieldName);
            }
        }
    }
}