WebMvcConfigurer 接口的配置类ExternalFastJsonConfig.java,如果项目中已经有实现 WebMvcConfigurer 的接口类,可以直接把ExternalFastJsonConfig.java里的核心代码放进去即可,不用再创建package com.liu.susu.common.config;
import com.alibaba.fastjson.serializer.SerializerFeature;
import com.alibaba.fastjson.serializer.ValueFilter;
import com.alibaba.fastjson.support.config.FastJsonConfig;
import com.alibaba.fastjson.support.spring.FastJsonHttpMessageConverter;
import com.liu.susu.common.util.DateUtils;
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.web.servlet.config.annotation.*;
import java.nio.charset.Charset;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
/**
* description 统一处理返回前端的json格式
* @author susu
**/
@Configuration
public class ExternalFastJsonConfig implements WebMvcConfigurer {
private static final String FORMAT = "yyyy-MM-dd HH:mm:ss";
private static SerializerFeature[] serializerFeatures = new SerializerFeature[]{
SerializerFeature.PrettyFormat,
SerializerFeature.WriteEnumUsingToString,
SerializerFeature.IgnoreNonFieldGetter
};
private static ValueFilter filter = new ValueFilter () {
public Object process(Object obj, String key, Object value) {
if(value==null){
// return "is null ???? I want to change the value!!!";
}else if("".equals(value.toString())){
return null;
}
if (value instanceof LocalDateTime){
// return "2022-07-29 10:43:22";
return DateUtils.getDateTimeStr((LocalDateTime)value);
}else if (value instanceof LocalDate){
return DateUtils.getDateStrYMD((LocalDate)value);
}else if (value instanceof Date){
return DateUtils.getDateStrYMD((Date)value);
}
return value;
}
};
@Bean
public HttpMessageConverter fastJsonHttpMessageConverters(){
FastJsonHttpMessageConverter fastConverter = new FastJsonHttpMessageConverter();
FastJsonConfig config = new FastJsonConfig();
config.setSerializerFeatures(serializerFeatures);
config.setDateFormat(FORMAT);
config.setSerializeFilters(filter);
fastConverter.setFastJsonConfig(config);
fastConverter.setDefaultCharset(Charset.forName("UTF-8"));
List<MediaType> mediaTypeList = new ArrayList<>();
// 解决中文乱码问题,相当于在Controller上的@RequestMapping中加了个属性produces = "application/json"
mediaTypeList.add(MediaType.APPLICATION_JSON);
fastConverter.setSupportedMediaTypes(mediaTypeList);
HttpMessageConverter<?> converter=fastConverter;
return converter;
}
@Override
public void configureMessageConverters(List<HttpMessageConverter<?>> converters) {
// converters.add(fastJsonHttpMessageConverters());
}
//解决跨域问题
@Override
public void addCorsMappings(CorsRegistry registry) {
registry.addMapping("/**")
.allowedOrigins("*")
.allowedMethods("GET", "HEAD", "POST", "PUT", "DELETE", "OPTIONS")
.allowCredentials(true)
.maxAge(3600)
.allowedHeaders("*");
}
@Override
public void addResourceHandlers(ResourceHandlerRegistry registry) {
// registry.addResourceHandler("/**").addResourceLocations(
// "classpath:/static/");
// registry.addResourceHandler("/doc.html").addResourceLocations(
// "classpath:/META-INF/resources/");
// registry.addResourceHandler("/webjars/**").addResourceLocations(
// "classpath:/META-INF/resources/webjars/");
registry.addResourceHandler("/**").addResourceLocations("/");
// super.addResourceHandlers(registry);
}
}
② DateUtils.java
ValueFilter 里分别处理了一下package com.liu.susu.common.util;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.ZoneId;
import java.time.format.DateTimeFormatter;
import java.util.Date;
/**
* @FileName DateUtils
* @Description
* @Author susu
**/
public class DateUtils {
private static final String FORMAT_1 = "yyyy-MM-dd HH:mm:ss";
private static final String FORMAT_2 = "yyyy-MM-dd";
/**
* description :把 LocalDate 类型转换成 "yyyy-MM-dd"
* @param localDate
* @return java.lang.String
* @author susu
*/
public static String getDateStrYMD(LocalDate localDate){
DateTimeFormatter dateTimeFormatter = DateTimeFormatter.ofPattern(FORMAT_2);
return dateTimeFormatter.format(localDate);
}
/**
* description :如果有时分秒直接返回(时分秒是0的),如果没有返回年月日
* @param date
* @return java.lang.String
* @author susu
*/
public static String getDateStrYMD(Date date){
LocalDateTime localDateTime = date.toInstant().atZone((ZoneId.systemDefault())).toLocalDateTime();
if (localDateTime.getHour()==0 && localDateTime.getSecond()==0 && localDateTime.getMinute()==0){
return getDateYMD(localDateTime);
}
return getDateTimeStr(localDateTime);
}
/**
* description :把 LocalDateTime 类型转换成 "yyyy-MM-dd"
* @param localDateTime
* @return java.lang.String
* @author susu
*/
public static String getDateYMD(LocalDateTime localDateTime){
DateTimeFormatter dateTimeFormatter = DateTimeFormatter.ofPattern(FORMAT_2);
return dateTimeFormatter.format(localDateTime);
}
/**
* description :把 LocalDateTime 类型转换成 "yyyy-MM-dd HH:mm:ss"
* @param localDateTime
* @return java.lang.String
* @author susu
*/
public static String getDateTimeStr(LocalDateTime localDateTime){
DateTimeFormatter dateTimeFormatter = DateTimeFormatter.ofPattern(FORMAT_1);
return dateTimeFormatter.format(localDateTime);
}
}
对于枚举的序列化不是很好用,我这边没有实现,如果有更好的方法,欢迎沟通交流
枚举序列化 MyEnumSerializer .java
package com.liu.susu.common;
import com.fasterxml.jackson.core.JsonGenerator;
import com.fasterxml.jackson.databind.JsonSerializer;
import com.fasterxml.jackson.databind.SerializerProvider;
import java.io.IOException;
/**
* description
* @author susu
* @date 2022-08-12
**/
public class MyEnumSerializer extends JsonSerializer<MyEnum> {
@Override
public void serialize(MyEnum value, JsonGenerator gen, SerializerProvider serializers) throws IOException {
gen.writeStartObject();
gen.writeFieldName("value");
gen.writeString(value.getValue().toString());
gen.writeFieldName("name");
gen.writeString(value.getName());
gen.writeEndObject();
}
}
public interface MyEnum<E extends Enum<?>, T> {
Object getValue();
String getName();
}
使用方式
方式1:在实体的属性上加注解:
@JSONField(serializeUsing = MyEnumSerializer.class)
方式2:在 MyEnum 上加注解:
@JSONType(serializer = MyEnumSerializer.class)
但是,验证试了一下,这两种方式都没有实现,具体怎么实现,或者是枚举序列化类有问题?我没再试,直接换了jackson,大家也可以参考下面一篇文章试试
fastjson枚举转换(序列化、反序列化)最新版本爬坑记录.
package com.liu.susu.common.config;
import com.fasterxml.jackson.core.JsonGenerator;
import com.fasterxml.jackson.core.JsonParser;
import com.fasterxml.jackson.databind.*;
import com.fasterxml.jackson.datatype.jsr310.deser.LocalDateDeserializer;
import com.fasterxml.jackson.datatype.jsr310.deser.LocalDateTimeDeserializer;
import com.fasterxml.jackson.datatype.jsr310.deser.LocalTimeDeserializer;
import com.fasterxml.jackson.datatype.jsr310.ser.LocalDateSerializer;
import com.fasterxml.jackson.datatype.jsr310.ser.LocalDateTimeSerializer;
import com.fasterxml.jackson.datatype.jsr310.ser.LocalTimeSerializer;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.boot.autoconfigure.jackson.Jackson2ObjectMapperBuilderCustomizer;
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.IOException;
import java.text.SimpleDateFormat;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.time.format.DateTimeFormatter;
import java.util.HashMap;
import java.util.Map;
/**
* description 统一处理返回前端的json格式
* @author susu
**/
@Configuration
public class ExternalJacksonConfig {
private static final String FORMAT = "yyyy-MM-dd HH:mm:ss";
private static final DateTimeFormatter FORMAT_YMD_TIME = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
private static final DateTimeFormatter FORMAT_YMD = DateTimeFormatter.ofPattern("yyyy-MM-dd");
private static final DateTimeFormatter FORMAT_TIME = DateTimeFormatter.ofPattern("HH:mm:ss");
@Bean
@Primary
@ConditionalOnMissingBean(ObjectMapper.class)
public ObjectMapper jacksonObjectMapper(Jackson2ObjectMapperBuilder builder) {
ObjectMapper objectMapper = builder.createXmlMapper(false).build();
objectMapper.setDateFormat(new SimpleDateFormat(FORMAT));
objectMapper.configure(MapperFeature.AUTO_DETECT_IS_GETTERS,false);
objectMapper.configure(SerializationFeature.WRITE_ENUMS_USING_TO_STRING,true);
//反序列化时
objectMapper.configure(JsonParser.Feature.ALLOW_UNQUOTED_CONTROL_CHARS, true);//允许出现特殊字符和转义符、
objectMapper.configure(JsonParser.Feature.ALLOW_SINGLE_QUOTES, true);//允许出现单引号
objectMapper.getSerializerProvider().setNullValueSerializer(new JsonSerializer<Object>() {
@Override
public void serialize(Object object, JsonGenerator value, SerializerProvider serializerProvider) throws IOException {
value.writeString("");
}
});
return objectMapper;
}
/**
* 处理 LocalDateTime LocalDate 的序列化和反序列化
* @return
*/
@Bean
public Jackson2ObjectMapperBuilderCustomizer jackson2ObjectMapperBuilderCustomizer() {
Map<Class<?>, JsonSerializer<?>> serializers = new HashMap<>();
serializers.put(LocalDateTime.class, new LocalDateTimeSerializer(FORMAT_YMD_TIME));
serializers.put(LocalDate.class, new LocalDateSerializer(FORMAT_YMD));
serializers.put(LocalTime.class, new LocalTimeSerializer(FORMAT_TIME));
Map<Class<?>, JsonDeserializer<?>> deserializers = new HashMap<>();
deserializers.put(LocalDateTime.class, new LocalDateTimeDeserializer(FORMAT_YMD_TIME));
deserializers.put(LocalDate.class, new LocalDateDeserializer(FORMAT_YMD));
deserializers.put(LocalTime.class, new LocalTimeDeserializer(FORMAT_TIME));
return builder -> builder.serializersByType(serializers).deserializersByType(deserializers);
}
}
@JsonFormat(shape = JsonFormat.Shape.OBJECT)@JsonSerialize(using = MyEnumSerializer.class)


ObjectMapper objectMapper = new ObjectMapper();
objectMapper.setDateFormat(new SimpleDateFormat(FORMAT));
JavaTimeModule javaTimeModule = new JavaTimeModule();
javaTimeModule.addSerializer(LocalDateTime.class, new LocalDateTimeSerializer(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")));
javaTimeModule.addSerializer(LocalDate.class, new LocalDateSerializer(DateTimeFormatter.ofPattern("yyyy-MM-dd")));
javaTimeModule.addSerializer(LocalTime.class, new LocalTimeSerializer(DateTimeFormatter.ofPattern("HH:mm:ss")));
javaTimeModule.addDeserializer(LocalDateTime.class, new LocalDateTimeDeserializer(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")));
javaTimeModule.addDeserializer(LocalDate.class, new LocalDateDeserializer(DateTimeFormatter.ofPattern("yyyy-MM-dd")));
javaTimeModule.addDeserializer(LocalTime.class, new LocalTimeDeserializer(DateTimeFormatter.ofPattern("HH:mm:ss")));
objectMapper.registerModule(javaTimeModule);