MvcConfiguration.java 8.08 KB
package cn.chnmuseum.party.conf;

import cn.chnmuseum.party.common.util.MyLocalDateSerializer;
import cn.chnmuseum.party.common.util.MyLocalDateTimeSerializer;
import com.alibaba.fastjson.PropertyNamingStrategy;
import com.alibaba.fastjson.serializer.SerializeConfig;
import com.alibaba.fastjson.serializer.SerializerFeature;
import com.alibaba.fastjson.support.config.FastJsonConfig;
import com.alibaba.fastjson.support.spring.FastJsonHttpMessageConverter;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.MediaType;
import org.springframework.http.converter.ByteArrayHttpMessageConverter;
import org.springframework.http.converter.HttpMessageConverter;
import org.springframework.http.converter.StringHttpMessageConverter;
import org.springframework.http.converter.json.MappingJackson2HttpMessageConverter;
import org.springframework.web.servlet.ModelAndView;
import org.springframework.web.servlet.config.annotation.CorsRegistry;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurationSupport;
import org.springframework.web.servlet.handler.HandlerInterceptorAdapter;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.nio.charset.StandardCharsets;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;

/**
 * MVC配置
 */
@Configuration
public class MvcConfiguration extends WebMvcConfigurationSupport {

    /**
     * 后置跨域支持【当出现跨域请求,此处会放在拦截器最后执行,CORS失效】
     *
     * @param registry
     */
    @Override
    public void addCorsMappings(CorsRegistry registry) {
        registry.addMapping("/**")
                .allowedOriginPatterns("*")
                .allowedHeaders("*")
                .allowedMethods("*")
                .allowCredentials(true)
                .maxAge(3600);
    }


    /**
     * 配置消息转换器
     *
     * @param converters
     */
    @Override
    public void configureMessageConverters(List<HttpMessageConverter<?>> converters) {
        //0.先移除jackson转换器,springBoot1.x可以不排除
        converters.removeIf(converter -> converter instanceof MappingJackson2HttpMessageConverter);

        //1.需要定义一个convert转换消息的对象;
        FastJsonHttpMessageConverter fastJsonHttpMessageConverter = new FastJsonHttpMessageConverter();
        StringHttpMessageConverter stringHttpMessageConverter = new StringHttpMessageConverter();
        ByteArrayHttpMessageConverter byteArrayHttpMessageConverter = new ByteArrayHttpMessageConverter();

        //2.添加fastJson的配置信息,比如:是否要格式化返回的json数据;
        FastJsonConfig fastJsonConfig = new FastJsonConfig();
        fastJsonConfig.setSerializerFeatures(
                SerializerFeature.PrettyFormat,                     // 结果格式化
                 SerializerFeature.WriteMapNullValue,             // 输出空值字段
                SerializerFeature.WriteNullStringAsEmpty,           // String如果为null,输出为"",而不是null
                SerializerFeature.DisableCircularReferenceDetect,   // 消除对同一对象循环引用的问题
                SerializerFeature.WriteNullListAsEmpty,             // List集合如果为null,输出为[],而不是null
                // SerializerFeature.BrowserCompatible,             // 将中文都会序列化为[\u0000]格式,字节数虽然会多一些,但是能兼容IE 6
                SerializerFeature.WriteDateUseDateFormat);          // 全局修改日期格式

        // 设置编码
        fastJsonConfig.setCharset(StandardCharsets.UTF_8);
        fastJsonConfig.setDateFormat("yyyy-MM-dd");

        // 设置数字转化问题
        SerializeConfig serializeConfig = SerializeConfig.globalInstance;
//        serializeConfig.put(BigInteger.class, ToStringSerializer.instance);
//        serializeConfig.put(Long.class, ToStringSerializer.instance);
//        serializeConfig.put(Long.TYPE, ToStringSerializer.instance);
        serializeConfig.setPropertyNamingStrategy(PropertyNamingStrategy.CamelCase);
        serializeConfig.put(LocalDateTime.class, new MyLocalDateTimeSerializer("yyyy-MM-dd HH:mm:ss"));
        serializeConfig.put(LocalDate.class, new MyLocalDateSerializer("yyyy-MM-dd"));
        fastJsonConfig.setSerializeConfig(serializeConfig);

        //3.处理中文乱码问题
        List<MediaType> fastMediaTypes = new ArrayList<>();
        fastMediaTypes.add(MediaType.APPLICATION_JSON);
        fastMediaTypes.add(MediaType.TEXT_PLAIN);
        fastMediaTypes.add(MediaType.APPLICATION_FORM_URLENCODED);
        fastMediaTypes.add(MediaType.TEXT_HTML);
        fastMediaTypes.add(MediaType.MULTIPART_FORM_DATA);

        //4.在convert中添加配置信息
        fastJsonHttpMessageConverter.setSupportedMediaTypes(fastMediaTypes);
        fastJsonHttpMessageConverter.setFastJsonConfig(fastJsonConfig);

        //5.将convert添加到converters当中
        converters.add(0, fastJsonHttpMessageConverter);
        converters.add(0, stringHttpMessageConverter);
        converters.add(0, byteArrayHttpMessageConverter);
    }

    /**
     * 启用@EnableWebMvc后,properties文件中的静态路径失效,必须覆盖后重新制定
     * 配置静态访问资源
     *
     * @param registry
     */
    @Override
    public void addResourceHandlers(ResourceHandlerRegistry registry) {
        // swagger2配置
        registry.addResourceHandler("/swagger-ui.html")
                .addResourceLocations("classpath:/META-INF/resources/");
        registry.addResourceHandler("/webjars/**")
                .addResourceLocations("classpath:/META-INF/resources/webjars/");

        // 静态资源拦截
        registry.addResourceHandler("/**")
                .addResourceLocations("classpath:/META-INF/")
                .addResourceLocations("classpath:/META-INF/resources/")
                .addResourceLocations("classpath:/resources/")
                .addResourceLocations("classpath:/static/")
                .addResourceLocations("classpath:/public/")
                .addResourceLocations("classpath:/statics/")
                .addResourceLocations("classpath:/template/")
                .addResourceLocations("classpath:/");
    }
    /**
     * 添加自定义的拦截器
     * @author fxbin
     * @param registry
     */
    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        registry.addInterceptor(new MyInterceptor()).addPathPatterns("/**");
    }


    /**
     * 拦截器
     * @author fxbin
     * @version v1.0
     * @since 2018/11/7 1:25
     */
    class MyInterceptor extends HandlerInterceptorAdapter {
        @Override
        public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
            System.out.println("Interceptor preHandler method is running !");
            return super.preHandle(request, response, handler);
        }

        @Override
        public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
            System.out.println("Interceptor postHandler method is running !");
            super.postHandle(request, response, handler, modelAndView);
        }

        @Override
        public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
            System.out.println("Interceptor afterCompletion method is running !");
            super.afterCompletion(request, response, handler, ex);
        }

        @Override
        public void afterConcurrentHandlingStarted(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
            System.out.println("Interceptor afterConcurrentHandlingStarted method is running !");
            super.afterConcurrentHandlingStarted(request, response, handler);
        }
    }

}