美文网首页
记一次springboot通过jackson渲染到前端,出现大写

记一次springboot通过jackson渲染到前端,出现大写

作者: linyb极客之路 | 来源:发表于2023-04-03 09:51 被阅读0次

    前言

    最近业务部门接手了外包供应商的项目过来自己运维,该部门的小伙伴发现了一个问题,比如后端的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

    相关文章

      网友评论

          本文标题:记一次springboot通过jackson渲染到前端,出现大写

          本文链接:https://www.haomeiwen.com/subject/udpdddtx.html