or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

index.mdjackson-modules.mdobject-mapper-factory.mdproperty-naming.mdsubtype-discovery.md

property-naming.mddocs/

0

# Property Naming

1

2

Dropwizard Jackson provides flexible property naming support that allows classes to use either camelCase or snake_case JSON field names based on annotations.

3

4

## AnnotationSensitivePropertyNamingStrategy

5

6

A property naming strategy that conditionally applies snake_case naming based on the presence of the `@JsonSnakeCase` annotation.

7

8

```java { .api }

9

public class AnnotationSensitivePropertyNamingStrategy extends PropertyNamingStrategy {

10

public String nameForConstructorParameter(MapperConfig<?> config,

11

AnnotatedParameter ctorParam,

12

String defaultName)

13

public String nameForField(MapperConfig<?> config,

14

AnnotatedField field,

15

String defaultName)

16

public String nameForGetterMethod(MapperConfig<?> config,

17

AnnotatedMethod method,

18

String defaultName)

19

public String nameForSetterMethod(MapperConfig<?> config,

20

AnnotatedMethod method,

21

String defaultName)

22

}

23

```

24

25

**Behavior**:

26

- **Annotated Classes**: Uses snake_case naming for classes annotated with `@JsonSnakeCase`

27

- **Default Classes**: Uses default Jackson naming (typically camelCase) for non-annotated classes

28

- **Null Safety**: Handles null parameters gracefully, returning the default name

29

30

## JsonSnakeCase Annotation

31

32

Marker annotation that indicates a class should use snake_case property names in JSON serialization.

33

34

```java { .api }

35

@Target(ElementType.TYPE)

36

@Retention(RetentionPolicy.RUNTIME)

37

@JacksonAnnotation

38

public @interface JsonSnakeCase {

39

}

40

```

41

42

**Properties**:

43

- **Target**: Can only be applied to classes/interfaces (ElementType.TYPE)

44

- **Retention**: Available at runtime for reflection

45

- **Jackson Integration**: Recognized as a Jackson annotation

46

47

## Usage Examples

48

49

### Basic Snake Case Usage

50

51

```java

52

@JsonSnakeCase

53

public class UserPreferences {

54

private String displayName;

55

private boolean enableNotifications;

56

private int maxRetryCount;

57

58

// constructors, getters, setters...

59

}

60

61

ObjectMapper mapper = Jackson.newObjectMapper();

62

UserPreferences prefs = new UserPreferences("John Doe", true, 3);

63

64

String json = mapper.writeValueAsString(prefs);

65

// Result: {"display_name":"John Doe","enable_notifications":true,"max_retry_count":3}

66

```

67

68

### Mixed Naming Strategies

69

70

```java

71

// This class uses default camelCase

72

public class StandardConfig {

73

private String serverName;

74

private int portNumber;

75

76

// constructors, getters, setters...

77

}

78

79

// This class uses snake_case

80

@JsonSnakeCase

81

public class DatabaseConfig {

82

private String connectionUrl;

83

private int maxConnections;

84

85

// constructors, getters, setters...

86

}

87

88

ObjectMapper mapper = Jackson.newObjectMapper();

89

90

StandardConfig standard = new StandardConfig("api-server", 8080);

91

DatabaseConfig database = new DatabaseConfig("jdbc:postgresql://localhost/db", 10);

92

93

String standardJson = mapper.writeValueAsString(standard);

94

// Result: {"serverName":"api-server","portNumber":8080}

95

96

String databaseJson = mapper.writeValueAsString(database);

97

// Result: {"connection_url":"jdbc:postgresql://localhost/db","max_connections":10}

98

```

99

100

### Constructor Parameter Handling

101

102

```java

103

@JsonSnakeCase

104

public class ApiKey {

105

private final String keyValue;

106

private final long createdAt;

107

108

public ApiKey(@JsonProperty("key_value") String keyValue,

109

@JsonProperty("created_at") long createdAt) {

110

this.keyValue = keyValue;

111

this.createdAt = createdAt;

112

}

113

114

// getters...

115

}

116

117

ObjectMapper mapper = Jackson.newObjectMapper();

118

119

// Both serialization and deserialization use snake_case

120

String json = "{\"key_value\":\"abc123\",\"created_at\":1640995200000}";

121

ApiKey key = mapper.readValue(json, ApiKey.class);

122

123

String serialized = mapper.writeValueAsString(key);

124

// Result: {"key_value":"abc123","created_at":1640995200000}

125

```

126

127

## Integration with ObjectMapper

128

129

The naming strategy is automatically configured when using Jackson factory methods:

130

131

```java

132

ObjectMapper mapper = Jackson.newObjectMapper();

133

// AnnotationSensitivePropertyNamingStrategy is automatically set

134

135

ObjectMapper minimal = Jackson.newMinimalObjectMapper();

136

// Does NOT include the custom naming strategy (uses default)

137

```

138

139

## Compatibility

140

141

The naming strategy works with:

142

- **Field-based** serialization/deserialization

143

- **Getter/Setter** method-based serialization/deserialization

144

- **Constructor parameter** deserialization with preserved parameter names

145

- **Mixed approaches** within the same application

146

147

**Note**: The strategy only affects classes directly annotated with `@JsonSnakeCase`. Nested objects follow their own annotation rules.