如何使用Jackson全局定义命名约定

时间:2016-08-17 06:36:04

标签: java spring spring-boot jackson

我和杰克逊一起使用Spring。我有几个像这样的方法:

@RequestMapping(value = "/myURL", method = RequestMethod.GET)
public @ResponseBody Foo getFoo()  {
    // get foo
    return foo;
}

序列化的Foo类很大,有很多成员。序列化没问题,使用注释或自定义序列化器。

我唯一能解决的是如何定义命名约定。我想对所有序列化使用snake_case。

那么如何定义全局序列化的命名约定?

如果不可能,那么本地解决方案就必须这样做。

3 个答案:

答案 0 :(得分:5)

不确定如何在全局范围内执行此操作,但这是在JSON对象级别执行此操作的方法,而不是每个单独的属性:

python Exporter.py --querysearch 'olympics' --since 2016-01-01 --until 2016-08-04 --maxtweets 10000

会产生json:

@JsonNaming(PropertyNamingStrategy.SnakeCaseStrategy.class)
public class Foo {
    private String myBeanName;
    //...
}

答案 1 :(得分:2)

实际上,有一个非常简单的答案:

@Bean
public Jackson2ObjectMapperBuilder jacksonBuilder() {
    Jackson2ObjectMapperBuilder b = new Jackson2ObjectMapperBuilder();
    b.propertyNamingStrategy(PropertyNamingStrategy.SNAKE_CASE);
    return b;
}

我把它添加到我的主要内容中:

@SpringBootApplication
public class Application {
    public static void main(String [] args) {
        SpringApplication.run(Application.class, args);
    }

    @Bean
    public Jackson2ObjectMapperBuilder jacksonBuilder() {
        Jackson2ObjectMapperBuilder b = new Jackson2ObjectMapperBuilder();
        b.propertyNamingStrategy(PropertyNamingStrategy.SNAKE_CASE);
        return b;
    }
}

答案 2 :(得分:1)

mapper有一个PropertyNamingStrategy的setter(设置自定义属性命名策略的方法。)

在tes示例中查看它是如何工作的:

    @Test
    public void namingStrategy() throws Exception {
        final ObjectMapper mapper = new ObjectMapper();
        mapper.setPropertyNamingStrategy(new PropertyNamingStrategy.PropertyNamingStrategyBase() {
            @Override
            public String translate(String s) {
                return s.toUpperCase();
            }
        });

        final String json = mapper.writerWithDefaultPrettyPrinter().writeValueAsString(new SomePojo("uuid_1", "user_1", "Bruce", "W.", 51));
        System.out.println(json);
    }

    public static class SomePojo {
        private String someIdAttachedToIt;
        private String username;
        private String fistName;
        private String lastName;
        private int age;

        public SomePojo(String someIdAttachedToIt, String username, String fistName, String lastName, int age) {
            this.someIdAttachedToIt = someIdAttachedToIt;
            this.username = username;
            this.fistName = fistName;
            this.lastName = lastName;
            this.age = age;
        }

        public String getSomeIdAttachedToIt() {
            return someIdAttachedToIt;
        }

        public String getUsername() {
            return username;
        }

        public String getFistName() {
            return fistName;
        }

        public String getLastName() {
            return lastName;
        }

        public int getAge() {
            return age;
        }
    }

输出:

{
  "SOMEIDATTACHEDTOIT" : "uuid_1",
  "USERNAME" : "user_1",
  "FISTNAME" : "Bruce",
  "LASTNAME" : "W.",
  "AGE" : 51
}

提供策略(我使用LOWERCASE作为示例)

PropertyNamingStrategy.CAMEL_CASE_TO_LOWER_CASE_WITH_UNDERSCORES
PropertyNamingStrategy.SNAKE_CASE

要在Spring中全局添加策略,您至少可以通过以下两种方式实现:

  • 将mapper模块声明为包含命名策略的bean
  • 使用您想要的自定义对象映射器

简短版:

@Configuration
    public static class Config {
        @Bean
        public Module module() {
            return new SimpleModule() {
                @Override
                protected SimpleModule setNamingStrategy(PropertyNamingStrategy naming) {
                    super.setNamingStrategy(new PropertyNamingStrategy.PropertyNamingStrategyBase() {
                        @Override
                        public String translate(String propertyName) {
                            // example: "propertyName" -> "PROPERTYNAME"
                            return propertyName.toUpperCase();
                        }
                    });
                    return this;
                }
            };
        }
    }

长版:

为jackson模块声明bean:

// config auto scan by spring
@Configuration
public static class ConfigurationClass {

    // declare the module as a bean
    @Bean
    public Module myJsonModule() {
        return new MySimpleModule();
    }
}

// jackson mapper module to customize mapping
private static class MySimpleModule extends SimpleModule {
    @Override
    protected SimpleModule setNamingStrategy(PropertyNamingStrategy naming) {
        return super.setNamingStrategy(new MyNameStrategy());
    }
}

// your naming strategy
private static class MyNameStrategy extends PropertyNamingStrategy.PropertyNamingStrategyBase {
    @Override
    public String translate(String propertyName) {
        return propertyName.toUpperCase();
    }

}

您也可以在xml中声明bean。

它不会覆盖明确定义道具名称的@JsonProperty。