|
@@ -0,0 +1,197 @@
|
|
|
|
+package cn.sino.mark.common.config;
|
|
|
|
+
|
|
|
|
+import cn.sino.mark.common.processor.JsonModelAttributeMethodProcessor;
|
|
|
|
+import com.fasterxml.jackson.annotation.JsonAutoDetect;
|
|
|
|
+import com.fasterxml.jackson.annotation.JsonInclude;
|
|
|
|
+import com.fasterxml.jackson.annotation.JsonTypeInfo;
|
|
|
|
+import com.fasterxml.jackson.annotation.PropertyAccessor;
|
|
|
|
+import com.fasterxml.jackson.databind.DeserializationFeature;
|
|
|
|
+import com.fasterxml.jackson.databind.MapperFeature;
|
|
|
|
+import com.fasterxml.jackson.databind.ObjectMapper;
|
|
|
|
+import com.fasterxml.jackson.databind.SerializationFeature;
|
|
|
|
+import com.fasterxml.jackson.databind.jsontype.impl.LaissezFaireSubTypeValidator;
|
|
|
|
+import com.fasterxml.jackson.databind.module.SimpleModule;
|
|
|
|
+import com.fasterxml.jackson.databind.ser.std.ToStringSerializer;
|
|
|
|
+import com.fasterxml.jackson.datatype.jdk8.Jdk8Module;
|
|
|
|
+import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule;
|
|
|
|
+import com.fasterxml.jackson.datatype.jsr310.deser.LocalDateDeserializer;
|
|
|
|
+import com.fasterxml.jackson.datatype.jsr310.deser.LocalDateTimeDeserializer;
|
|
|
|
+import com.fasterxml.jackson.datatype.jsr310.ser.LocalDateSerializer;
|
|
|
|
+import com.fasterxml.jackson.datatype.jsr310.ser.LocalDateTimeSerializer;
|
|
|
|
+import com.fasterxml.jackson.module.paramnames.ParameterNamesModule;
|
|
|
|
+import org.springframework.boot.web.client.RestTemplateBuilder;
|
|
|
|
+import org.springframework.context.annotation.Bean;
|
|
|
|
+import org.springframework.context.annotation.Configuration;
|
|
|
|
+import org.springframework.http.MediaType;
|
|
|
|
+import org.springframework.http.converter.HttpMessageConverter;
|
|
|
|
+import org.springframework.http.converter.StringHttpMessageConverter;
|
|
|
|
+import org.springframework.http.converter.json.MappingJackson2HttpMessageConverter;
|
|
|
|
+import org.springframework.web.client.RestTemplate;
|
|
|
|
+import org.springframework.web.method.support.HandlerMethodArgumentResolver;
|
|
|
|
+import org.springframework.web.multipart.commons.CommonsMultipartResolver;
|
|
|
|
+import org.springframework.web.servlet.config.annotation.CorsRegistry;
|
|
|
|
+import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry;
|
|
|
|
+import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
|
|
|
|
+import springfox.documentation.builders.ApiInfoBuilder;
|
|
|
|
+import springfox.documentation.builders.ParameterBuilder;
|
|
|
|
+import springfox.documentation.builders.RequestHandlerSelectors;
|
|
|
|
+import springfox.documentation.schema.ModelRef;
|
|
|
|
+import springfox.documentation.service.Parameter;
|
|
|
|
+import springfox.documentation.spi.DocumentationType;
|
|
|
|
+import springfox.documentation.spring.web.plugins.Docket;
|
|
|
|
+
|
|
|
|
+import java.time.Duration;
|
|
|
|
+import java.time.LocalDate;
|
|
|
|
+import java.time.LocalDateTime;
|
|
|
|
+import java.time.format.DateTimeFormatter;
|
|
|
|
+import java.util.ArrayList;
|
|
|
|
+import java.util.List;
|
|
|
|
+
|
|
|
|
+@Configuration
|
|
|
|
+public class WebConfig implements WebMvcConfigurer {
|
|
|
|
+ /**
|
|
|
|
+ * 格式化类型
|
|
|
|
+ */
|
|
|
|
+ public static final String YMDHMS2 = "yyyy-MM-dd HH:mm:ss";
|
|
|
|
+ public static final String YMD2 = "yyyy-MM-dd";
|
|
|
|
+ /**
|
|
|
|
+ * 上传文件最大体积
|
|
|
|
+ */
|
|
|
|
+ private static final Long MAX_UPLOAD_SIZE = 50 * 1024 * 1024L;
|
|
|
|
+
|
|
|
|
+ /**
|
|
|
|
+ * 重写ObjectMapper
|
|
|
|
+ *
|
|
|
|
+ * @return ObjectMapper
|
|
|
|
+ */
|
|
|
|
+ @Bean
|
|
|
|
+ public ObjectMapper markObjectMapper() {
|
|
|
|
+ var objectMapper = new ObjectMapper();
|
|
|
|
+ objectMapper.configure(SerializationFeature.INDENT_OUTPUT, true)
|
|
|
|
+ .setSerializationInclusion(JsonInclude.Include.ALWAYS)
|
|
|
|
+ .configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false)
|
|
|
|
+ .setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY)
|
|
|
|
+ .registerModule(new ParameterNamesModule()).registerModule(new Jdk8Module())
|
|
|
|
+ .registerModule(javaTimeModule())
|
|
|
|
+ .registerModule(longStrModule());
|
|
|
|
+ return objectMapper;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ private JavaTimeModule javaTimeModule() {
|
|
|
|
+ var javaTimeModule = new JavaTimeModule();
|
|
|
|
+ javaTimeModule.addSerializer(LocalDate.class, new LocalDateSerializer(DateTimeFormatter.ofPattern(YMD2)));
|
|
|
|
+ javaTimeModule.addDeserializer(LocalDate.class, new LocalDateDeserializer(DateTimeFormatter.ofPattern(YMD2)));
|
|
|
|
+ javaTimeModule.addSerializer(LocalDateTime.class, new LocalDateTimeSerializer(DateTimeFormatter.ofPattern(YMDHMS2)));
|
|
|
|
+ javaTimeModule.addDeserializer(LocalDateTime.class, new LocalDateTimeDeserializer(DateTimeFormatter.ofPattern(YMDHMS2)));
|
|
|
|
+ return javaTimeModule;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ /**
|
|
|
|
+ * TODO 注意
|
|
|
|
+ * @return
|
|
|
|
+ */
|
|
|
|
+ private SimpleModule longStrModule() {
|
|
|
|
+ SimpleModule simpleModule = new SimpleModule();
|
|
|
|
+ simpleModule.addSerializer(Long.class, ToStringSerializer.instance);
|
|
|
|
+ simpleModule.addSerializer(Long.TYPE, ToStringSerializer.instance);
|
|
|
|
+ return simpleModule;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ @Bean
|
|
|
|
+ public ObjectMapper redisObjectMapper() {
|
|
|
|
+ var objectMapper = new ObjectMapper();
|
|
|
|
+ objectMapper.configure(MapperFeature.USE_ANNOTATIONS, false)
|
|
|
|
+ .configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false)
|
|
|
|
+ .setSerializationInclusion(JsonInclude.Include.NON_NULL)
|
|
|
|
+ .setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY)
|
|
|
|
+ //必须配置,反序列化回来后信息不对
|
|
|
|
+ .activateDefaultTyping(LaissezFaireSubTypeValidator.instance,
|
|
|
|
+ ObjectMapper.DefaultTyping.NON_FINAL, JsonTypeInfo.As.PROPERTY)
|
|
|
|
+ .registerModule(new ParameterNamesModule()).registerModule(new Jdk8Module())
|
|
|
|
+ .registerModule(javaTimeModule());
|
|
|
|
+ return objectMapper;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ @Bean
|
|
|
|
+ public MappingJackson2HttpMessageConverter jackson2HttpMessageConverter() {
|
|
|
|
+ return new MappingJackson2HttpMessageConverter(markObjectMapper());
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ /**
|
|
|
|
+ * 配置json日期序列化和反序列化
|
|
|
|
+ *
|
|
|
|
+ * @param converters 转换器列表
|
|
|
|
+ */
|
|
|
|
+ @Override
|
|
|
|
+ public void configureMessageConverters(List<HttpMessageConverter<?>> converters) {
|
|
|
|
+ converters.add(jackson2HttpMessageConverter());
|
|
|
|
+ StringHttpMessageConverter stringConverter = new StringHttpMessageConverter();
|
|
|
|
+ stringConverter.setSupportedMediaTypes(List.of(MediaType.TEXT_PLAIN));
|
|
|
|
+ converters.add(stringConverter);
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ /**
|
|
|
|
+ * 添加自定义参数解析器
|
|
|
|
+ *
|
|
|
|
+ * @param argumentResolvers 方法参数转换器
|
|
|
|
+ */
|
|
|
|
+ @Override
|
|
|
|
+ public void addArgumentResolvers(List<HandlerMethodArgumentResolver> argumentResolvers) {
|
|
|
|
+ argumentResolvers.add(new JsonModelAttributeMethodProcessor(true, jackson2HttpMessageConverter()));
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ @Override
|
|
|
|
+ public void addCorsMappings(CorsRegistry registry) {
|
|
|
|
+// registry.addMapping("/**");
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ @Override
|
|
|
|
+ public void addResourceHandlers(ResourceHandlerRegistry registry) {
|
|
|
|
+ registry.addResourceHandler("swagger-ui.html").addResourceLocations("classpath:/META-INF/resources/");
|
|
|
|
+ registry.addResourceHandler("/webjars/**").addResourceLocations("classpath:/META-INF/resources/webjars/");
|
|
|
|
+ registry.addResourceHandler("doc.html").addResourceLocations("classpath:/META-INF/resources/");
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ @Bean
|
|
|
|
+ public Docket docket() {
|
|
|
|
+ ParameterBuilder ticketPar = new ParameterBuilder();
|
|
|
|
+ List<Parameter> pars = new ArrayList<>();
|
|
|
|
+ ticketPar.name("X-USER-ID").description("user ticket")
|
|
|
|
+ .modelRef(new ModelRef("string")).parameterType("header")
|
|
|
|
+ .required(false).build();
|
|
|
|
+ pars.add(ticketPar.build()); //根据每个方法名也知道当前方法在设置什么参数
|
|
|
|
+
|
|
|
|
+ return new Docket(DocumentationType.SWAGGER_12)
|
|
|
|
+ .groupName("飞书标注系统")
|
|
|
|
+ .select()
|
|
|
|
+ .apis(RequestHandlerSelectors.any())
|
|
|
|
+ .build()
|
|
|
|
+ .globalOperationParameters(pars)
|
|
|
|
+ .apiInfo(new ApiInfoBuilder()
|
|
|
|
+ .title("api swagger document")
|
|
|
|
+ .description("前后端联调swagger api 文档")
|
|
|
|
+ .version("1.0.0")
|
|
|
|
+ .build());
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+
|
|
|
|
+ /**
|
|
|
|
+ * 超出体积上线后抛出MaxUploadSizeExceededException异常(common包公共处理逻辑)
|
|
|
|
+ */
|
|
|
|
+ @Bean
|
|
|
|
+ public CommonsMultipartResolver commonsMultipartResolver() {
|
|
|
|
+ var multipartResolver = new CommonsMultipartResolver();
|
|
|
|
+ multipartResolver.setResolveLazily(true);
|
|
|
|
+ multipartResolver.setMaxUploadSizePerFile(MAX_UPLOAD_SIZE);
|
|
|
|
+ multipartResolver.setMaxUploadSize(MAX_UPLOAD_SIZE);
|
|
|
|
+ return multipartResolver;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ @Bean
|
|
|
|
+ public RestTemplate restTemplate(RestTemplateBuilder restTemplateBuilder) {
|
|
|
|
+ return restTemplateBuilder
|
|
|
|
+ .setConnectTimeout(Duration.ofSeconds(30))
|
|
|
|
+ .setReadTimeout(Duration.ofSeconds(30))
|
|
|
|
+ .build();
|
|
|
|
+ }
|
|
|
|
+}
|