专注于 JetBrains IDEA 全家桶,永久激活,教程
持续更新 PyCharm,IDEA,WebStorm,PhpStorm,DataGrip,RubyMine,CLion,AppCode 永久激活教程

从零开始改造spring项目-定制rest接口返回格式

本次改造主要解决如下问题:

基础篇

1、 如果参数为空或者为empty就不返回,节省网络流量。
2、 配置全局统一的时间格式
3、 char[] 数组返回String问题

进阶篇

1、 如何设置当String为null的时候,返回””

spring默认情况下使用jackson作为bean转json处理工具,所以我就以spring的默认配置为基础,添加一些自定义的配置。因为定制rest接口没啥逻辑可言,主要就是熟悉一下各个配置在那边设置,所以先给出最终的配置文件

@Configuration
public class RestResponseConfig {

    @Autowired(required = false)
    private List<BeanSerializerModifier> modifierList;

    @Bean
    public HttpMessageConverters message() {
        return new HttpMessageConverters(getHttpMessageConverter());
    }

    private HttpMessageConverter getHttpMessageConverter() {
        if (modifierList != null && modifierList.size() > 0) {
            return new MappingJackson2HttpMessageConverter(wrapper());
        }
        return new MappingJackson2HttpMessageConverter(getObjectMapper());
    }

    private ObjectMapper wrapper() {
        ObjectMapper objectMapper = getObjectMapper();
        objectMapper.setSerializerFactory(getSerializerFactory(objectMapper));
        return objectMapper;
    }

    private SerializerFactory getSerializerFactory(ObjectMapper objectMapper) {
        SerializerFactory factory = objectMapper.getSerializerFactory();
        for (BeanSerializerModifier modifier : modifierList) {
            factory = factory.withSerializerModifier(modifier);
        }
        return factory;
    }

    private ObjectMapper getObjectMapper() {
        return Jackson2ObjectMapperBuilder.json()
                                          .modules(getModule())
                                          .featuresToEnable(enableFeature())
                                          .featuresToDisable(disableFeature())
                                          .serializationInclusion(JsonInclude.Include.NON_EMPTY)
                                          .timeZone(TimeZone.getTimeZone(ZoneId.of("GMT+8")))
                                          .build();
    }

    private Module getModule() {
        SimpleModule module = new SimpleModule();
        module.addSerializer(LocalDateTime.class, new LocalDateTimeSerializer(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")));
        module.addSerializer(LocalDate.class, new LocalDateSerializer(DateTimeFormatter.ofPattern("yyyy-MM-dd")));
        module.addSerializer(LocalTime.class, new LocalTimeSerializer(DateTimeFormatter.ofPattern("HH:mm:ss")));
        module.addDeserializer(LocalDateTime.class, new LocalDateTimeDeserializer(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")));
        module.addDeserializer(LocalDate.class, new LocalDateDeserializer(DateTimeFormatter.ofPattern("yyyy-MM-dd")));
        module.addDeserializer(LocalTime.class, new LocalTimeDeserializer(DateTimeFormatter.ofPattern("HH:mm:ss")));
        return module;
    }

    private Object[] enableFeature() {
        return new Object[]{
                SerializationFeature.WRITE_CHAR_ARRAYS_AS_JSON_ARRAYS
//                , JsonGenerator.Feature.WRITE_NUMBERS_AS_STRINGS
        };
    }

    private Object[] disableFeature() {
        return new Object[]{SerializationFeature.WRITE_DATES_AS_TIMESTAMPS};
    }
}

基础篇问题

1、 如果参数为空或者为empty就不返回,节省网络流量。

在getObjectMapper方法下面serializationInclusion属性,jackson提供了如下集中选择常用的就是ALWAYS,NON_NULL,NON_EMPTY

ALWAYS,
NON_NULL,
NON_ABSENT,
NON_EMPTY,
NON_DEFAULT,
CUSTOM,
USE_DEFAULTS;

举个例子,现在有一个pojo

public class Pojo {
    private String name;
}

当他作为返回值的时候,如果你的配置为ALWAYS,那么即便name为null,你也会收到返回值。

{
    "name":null
}

但是当选择NON_NULL的时候,如果name为null的话,我们就不会收到这个属性了。

{

}

如果name不为null,而是””,这样的话接口还是会收到返回

{
    "name":""
}

如果选择NON_EMPTY,那么只有当那么不为null,且不为””,接口才会收到返回值。

1、 配置全局统一的时间格式

在默认配置下 LocalDateTime 类的格式是这样的

"time":"2019-10-21T12:29:34"

其实这个到不是说一定要改,而是各种需求的变化层出不穷,我遇到过有的地方专门以 yyyyMMddHHmmss 这种格式来传递时间的。所以我们还是需要掌握一下自定义的方法。

    private Module getModule() {
        SimpleModule module = new SimpleModule();
        module.addSerializer(LocalDateTime.class, new LocalDateTimeSerializer(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")));
        module.addSerializer(LocalDate.class, new LocalDateSerializer(DateTimeFormatter.ofPattern("yyyy-MM-dd")));
        module.addSerializer(LocalTime.class, new LocalTimeSerializer(DateTimeFormatter.ofPattern("HH:mm:ss")));
        module.addDeserializer(LocalDateTime.class, new LocalDateTimeDeserializer(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")));
        module.addDeserializer(LocalDate.class, new LocalDateDeserializer(DateTimeFormatter.ofPattern("yyyy-MM-dd")));
        module.addDeserializer(LocalTime.class, new LocalTimeDeserializer(DateTimeFormatter.ofPattern("HH:mm:ss")));
        return module;
    }

方法就在getModule这儿。SimpleModule这个类,我们这样配置的意思就是如果遇到LocalDateTime类,就以 LocalDateTimeSerializer(DateTimeFormatter.ofPattern(“yyyy-MM-dd HH:mm:ss”))来处理该类的序列化,反序列化也一样。所以在这边指定日期的格式就可以了。

1、 char[] 数组返回String问题

在默认情况下 char[] 数组序列化的时候会变为字符串

private char[] chars;
//输入
"chars":["a","b"]
//输出
"chars": "ab"

该配置在enableFeature方法中

SerializationFeature.WRITE_CHAR_ARRAYS_AS_JSON_ARRAYS

只要设置了WRITE_CHAR_ARRAYS_AS_JSON_ARRAYS这个属性,char[] 数组,便可以以数组的形式序列化了。

基础篇到这儿就结束了,已经差不多够解决一般性的需求。

进阶篇问题

1、 如何设置当String为null的时候,返回””

不要问我为什么要这样返回,因为我遇到的下游厂家是这么要求的。。。

要完成这个需求,首先得自定义一个序列化组件

@Component
public class NullStringSerializer extends StdSerializer<Object> {

    public NullStringSerializer() {
        super(Object.class);
    }

    @Override
    public void serialize(Object value, JsonGenerator gen, SerializerProvider provider) throws IOException {
        gen.writeString("");
    }
}

其次将该序列化组件设置为String类的null序列化组件

public class CustomNullSerializerModifier extends BeanSerializerModifier {

    @Autowired
    private NullStringSerializer nullStringSerializer;

    @Override
    public List<BeanPropertyWriter> changeProperties(SerializationConfig config, BeanDescription beanDesc, List<BeanPropertyWriter> beanProperties) {
        for (BeanPropertyWriter writer : beanProperties) {
            Class<?> rawClass = writer.getType().getRawClass();
            if(rawClass.isAssignableFrom(String.class)){
                writer.assignNullSerializer(nullStringSerializer);
            }
        }
        return beanProperties;
    }
}

这样我们上面的配置文件就可以读取到这个配置了。当String为null的时候,接口就会返回””了。


返回目录

文章永久链接:https://tech.souyunku.com/19136

未经允许不得转载:搜云库技术团队 » 从零开始改造spring项目-定制rest接口返回格式

JetBrains 全家桶,激活、破解、教程

提供 JetBrains 全家桶激活码、注册码、破解补丁下载及详细激活教程,支持 IntelliJ IDEA、PyCharm、WebStorm 等工具的永久激活。无论是破解教程,还是最新激活码,均可免费获得,帮助开发者解决常见激活问题,确保轻松破解并快速使用 JetBrains 软件。获取免费的破解补丁和激活码,快速解决激活难题,全面覆盖 2024/2025 版本!

联系我们联系我们