关于springboot:记一次springboot通过jackson渲染到前端出现大写字母变成小写问题

17次阅读

共计 3463 个字符,预计需要花费 9 分钟才能阅读完成。

前言

最近业务部门接手了外包供应商的我的项目过去本人运维,该部门的小伙伴发现了一个问题,比方后端的 DTO 有个属性名为 nPrice 的字段,通过 json 渲染到前端后,变成 nprice,而预期的字段是要为 nPrice。于是他们就找到咱们部门,心愿咱们能帮忙解决一下这个问题,本文就聊聊如何解决问题,至于为什么会呈现这个问题,前面留个彩蛋

解法

注: 本文的 json 都是通过 springboot 默认的 jackson 进行渲染解析,因而本文的解法都是针对 jackson

办法一:在属性字段上加 @JsonProperty 注解

示例

    @JsonProperty(value = "nPropriceFactory")
    private BigDecimal nPropriceFactory;

因为业务接手的我的项目的字段的属性大量都是首字母小写,第二个字母大写的模式,比方 nHelloWorld,因而业务部门的小伙伴,感觉一个个加太麻烦了,有没有更简洁点方法。于是就有了第二种办法

办法二:通过自定义 com.fasterxml.jackson.databind.PropertyNamingStrategy 策略

具体逻辑形如如下

public class CustomPropertyNamingStrategy extends PropertyNamingStrategy {


    @Override
    public String nameForGetterMethod(MapperConfig<?> config, AnnotatedMethod method, String defaultName) {if (isSpecialPropertyName(defaultName)) {
            // 将属性的 get 办法去除 get,而后首字母转小写
            return StringUtils.uncapitalize(method.getName().substring(3));
        }
        return super.nameForGetterMethod(config,method,defaultName);
    }



    @Override
    public String nameForSetterMethod(MapperConfig<?> config, AnnotatedMethod method, String defaultName) {if (isSpecialPropertyName(defaultName)) {
            // 将属性的 set 办法去除 set,而后首字母转小写
            return StringUtils.uncapitalize(method.getName().substring(3));
        }
        return super.nameForSetterMethod(config,method,defaultName);
    }

  


}

在 application.yml 做如下配置

spring:
  jackson:
    property-naming-strategy: com.github.lybgeek.jackson.CustomPropertyNamingStrategy

这样就能够解决了,不过业务部门的研发,基本上都是被惯坏的小孩,为了让他们更不便的应用,咱们就更近一步,也不要在 yml 进行配置了,让他们间接引入 jar 就好。于是咱们做了如下操作

public final class EnvUtils {private EnvUtils(){}

    private static final String JACKSON_PROPERTY_NAMING_STRATEGY_KEY = "spring.jackson.property-naming-strategy";


    public static void postProcessEnvironment(ConfigurableEnvironment environment){String isCustomJsonFormatEnaled = environment.getProperty(CUSTOM_JSON_FORMAT_ENABLE_KEY,"true");
        if("true".equalsIgnoreCase(isCustomJsonFormatEnaled)){setCustomJacksonPropertyNamingStrategy(environment);
        }
    }

    private static void setCustomJacksonPropertyNamingStrategy(ConfigurableEnvironment environment) {MutablePropertySources propertySources = environment.getPropertySources();
        Map<String, Object> mapPropertySource = new HashMap<>();
        mapPropertySource.put(JACKSON_PROPERTY_NAMING_STRATEGY_KEY, CustomPropertyNamingStrategy.class.getName());
        PropertySource propertySource = new MapPropertySource("custom-json-format-properties",mapPropertySource);
        propertySources.addFirst(propertySource);
    }

}
public class CustomJacksonFormatEnvironmentApplicationContextInitializer implements ApplicationContextInitializer {
    @Override
    public void initialize(ConfigurableApplicationContext applicationContext) {ConfigurableEnvironment environment = applicationContext.getEnvironment();
        EnvUtils.postProcessEnvironment(environment);

    }
}

在 resouce 下新建 META-INF/spring.factories, 并指定如下内容

org.springframework.context.ApplicationContextInitializer=\
com.github.lybgeek.jackson.env.CustomJacksonFormatEnvironmentApplicationContextInitializer

自此业务部门只有引入这个包,就能够解决 jackson 渲染到前端,呈现大写字母变成小写问题

:如果用实现 org.springframework.boot.env.EnvironmentPostProcessor 来实现属性配置也能够,不过要留神如果应用 springcloud,则可能会呈现在配置在 application.yml 的属性,通过

environment.getProperty(CUSTOM_JSON_FORMAT_ENABLE_KEY);

拿不到值的状况。因而举荐用实现 org.springframework.context.ApplicationContextInitializer 来进行环境变量获取或者设置

总结

以上两种形式,一种是采纳部分的形式,另一种是采纳全局的形式,采纳全局的形式,要做好测试,不然影响很大,咱们采纳全局的形式,一来是业务那边要求,二来是过后咱们和业务部门做好沟通,咱们依据他们的业务规定来做定制,并跟他们阐明采纳全局的形式可能遇到的问题。

至于为啥 jackson 渲染到前端,呈现大写字母变成小写问题,大家如果有空 debug 跟到 com.fasterxml.jackson.databind.util.BeanUtil#legacyManglePropertyName 这个办法,应该就会有答案。如果没空的话,就能够查看如下链接
https://blog.csdn.net/weixin_42511702/article/details/112520749
进行解读

demo 链接

https://github.com/lyb-geek/springboot-learning/tree/master/springboot-json-format

正文完
 0