0
# ObjectMapper Management
1
2
The ObjectMapper management system provides centralized creation and configuration of Jackson ObjectMapper instances. This allows for consistent configuration across your application while supporting multiple serialization bindings with different settings.
3
4
## Core ObjectMapper Provider
5
6
### JacksonObjectMapperProvider
7
8
The main provider class manages a registry of ObjectMapper instances, each with a unique binding name.
9
10
```scala { .api }
11
/**
12
* Registry of shared `ObjectMapper` instances, each with its unique `bindingName`.
13
*/
14
final class JacksonObjectMapperProvider(system: ExtendedActorSystem) extends Extension {
15
16
/**
17
* Returns an existing Jackson `ObjectMapper` or creates a new instance.
18
* The returned `ObjectMapper` must not be modified after creation.
19
*
20
* @param bindingName name of this `ObjectMapper`
21
* @param jsonFactory optional `JsonFactory` such as `CBORFactory`, for plain JSON use `None`
22
* @return configured ObjectMapper instance
23
*/
24
def getOrCreate(bindingName: String, jsonFactory: Option[JsonFactory]): ObjectMapper
25
26
/**
27
* Creates a new instance of a Jackson `ObjectMapper` with sensible defaults.
28
*
29
* @param bindingName name of this `ObjectMapper`
30
* @param jsonFactory optional `JsonFactory` such as `CBORFactory`, for plain JSON use `None`
31
* @return new ObjectMapper instance
32
*/
33
def create(bindingName: String, jsonFactory: Option[JsonFactory]): ObjectMapper
34
}
35
```
36
37
### Accessing the Provider
38
39
```scala
40
import akka.actor.ActorSystem
41
import akka.serialization.jackson.JacksonObjectMapperProvider
42
43
val system = ActorSystem("MySystem")
44
val provider = JacksonObjectMapperProvider(system)
45
```
46
47
### Getting ObjectMapper Instances
48
49
**For JSON serialization:**
50
```scala
51
val jsonMapper = provider.getOrCreate("my-json-binding", None)
52
```
53
54
**For CBOR serialization:**
55
```scala
56
import com.fasterxml.jackson.dataformat.cbor.CBORFactory
57
58
val cborMapper = provider.getOrCreate("my-cbor-binding", Some(new CBORFactory()))
59
```
60
61
**Creating fresh instances:**
62
```scala
63
// Create a new mapper instead of using cached version
64
val freshMapper = provider.create("my-binding", None)
65
```
66
67
## Custom ObjectMapper Factory
68
69
### JacksonObjectMapperFactory
70
71
For advanced customization, you can provide a custom factory that controls ObjectMapper creation and configuration.
72
73
```scala { .api }
74
/**
75
* Factory for creating and customizing ObjectMapper instances.
76
* Create a subclass and override methods to amend the defaults.
77
*/
78
class JacksonObjectMapperFactory {
79
80
/**
81
* Override to create custom ObjectMapper instance.
82
*
83
* @param bindingName name of this `ObjectMapper`
84
* @param jsonFactory optional `JsonFactory` for the mapper
85
* @return new ObjectMapper instance
86
*/
87
def newObjectMapper(bindingName: String, jsonFactory: JsonFactory): ObjectMapper
88
89
/**
90
* Override configured Jackson modules.
91
*
92
* @param bindingName binding name for this mapper
93
* @param configuredModules modules configured in akka.serialization.jackson.jackson-modules
94
* @return modules to be applied to the ObjectMapper
95
*/
96
def overrideConfiguredModules(bindingName: String, configuredModules: immutable.Seq[Module]): immutable.Seq[Module]
97
98
/**
99
* Override serialization features.
100
*
101
* @param bindingName binding name for this mapper
102
* @param configuredFeatures features configured in akka.serialization.jackson.serialization-features
103
* @return features to be applied to the ObjectMapper
104
*/
105
def overrideConfiguredSerializationFeatures(bindingName: String, configuredFeatures: immutable.Seq[(SerializationFeature, Boolean)]): immutable.Seq[(SerializationFeature, Boolean)]
106
107
/**
108
* Override deserialization features.
109
*
110
* @param bindingName binding name for this mapper
111
* @param configuredFeatures features configured in akka.serialization.jackson.deserialization-features
112
* @return features to be applied to the ObjectMapper
113
*/
114
def overrideConfiguredDeserializationFeatures(bindingName: String, configuredFeatures: immutable.Seq[(DeserializationFeature, Boolean)]): immutable.Seq[(DeserializationFeature, Boolean)]
115
116
/**
117
* Override mapper features.
118
*
119
* @param bindingName binding name for this mapper
120
* @param configuredFeatures features configured in akka.serialization.jackson.mapper-features
121
* @return features to be applied to the ObjectMapper
122
*/
123
def overrideConfiguredMapperFeatures(bindingName: String, configuredFeatures: immutable.Seq[(MapperFeature, Boolean)]): immutable.Seq[(MapperFeature, Boolean)]
124
125
/**
126
* Override JSON parser features.
127
*
128
* @param bindingName binding name for this mapper
129
* @param configuredFeatures features configured in akka.serialization.jackson.json-parser-features
130
* @return features to be applied to the ObjectMapper
131
*/
132
def overrideConfiguredJsonParserFeatures(bindingName: String, configuredFeatures: immutable.Seq[(JsonParser.Feature, Boolean)]): immutable.Seq[(JsonParser.Feature, Boolean)]
133
134
/**
135
* Override JSON generator features.
136
*
137
* @param bindingName binding name for this mapper
138
* @param configuredFeatures features configured in akka.serialization.jackson.json-generator-features
139
* @return features to be applied to the ObjectMapper
140
*/
141
def overrideConfiguredJsonGeneratorFeatures(bindingName: String, configuredFeatures: immutable.Seq[(JsonGenerator.Feature, Boolean)]): immutable.Seq[(JsonGenerator.Feature, Boolean)]
142
143
/**
144
* Override stream read features.
145
*
146
* @param bindingName binding name for this mapper
147
* @param configuredFeatures features configured in akka.serialization.jackson.stream-read-features
148
* @return features to be applied to the JsonFactory
149
*/
150
def overrideConfiguredStreamReadFeatures(bindingName: String, configuredFeatures: immutable.Seq[(StreamReadFeature, Boolean)]): immutable.Seq[(StreamReadFeature, Boolean)]
151
152
/**
153
* Override stream write features.
154
*
155
* @param bindingName binding name for this mapper
156
* @param configuredFeatures features configured in akka.serialization.jackson.stream-write-features
157
* @return features to be applied to the JsonFactory
158
*/
159
def overrideConfiguredStreamWriteFeatures(bindingName: String, configuredFeatures: immutable.Seq[(StreamWriteFeature, Boolean)]): immutable.Seq[(StreamWriteFeature, Boolean)]
160
161
/**
162
* Override JSON read features.
163
*
164
* @param bindingName binding name for this mapper
165
* @param configuredFeatures features configured in akka.serialization.jackson.json-read-features
166
* @return features to be applied to the JsonFactory
167
*/
168
def overrideConfiguredJsonReadFeatures(bindingName: String, configuredFeatures: immutable.Seq[(JsonReadFeature, Boolean)]): immutable.Seq[(JsonReadFeature, Boolean)]
169
170
/**
171
* Override JSON write features.
172
*
173
* @param bindingName binding name for this mapper
174
* @param configuredFeatures features configured in akka.serialization.jackson.json-write-features
175
* @return features to be applied to the JsonFactory
176
*/
177
def overrideConfiguredJsonWriteFeatures(bindingName: String, configuredFeatures: immutable.Seq[(JsonWriteFeature, Boolean)]): immutable.Seq[(JsonWriteFeature, Boolean)]
178
179
/**
180
* Override visibility settings.
181
*
182
* @param bindingName binding name for this mapper
183
* @param configuredFeatures visibility settings configured in akka.serialization.jackson.visibility
184
* @return visibility settings to be applied to the ObjectMapper
185
*/
186
def overrideConfiguredVisibility(bindingName: String, configuredFeatures: immutable.Seq[(PropertyAccessor, JsonAutoDetect.Visibility)]): immutable.Seq[(PropertyAccessor, JsonAutoDetect.Visibility)]
187
}
188
```
189
190
### Custom Factory Example
191
192
```scala
193
class MyCustomFactory extends JacksonObjectMapperFactory {
194
override def newObjectMapper(bindingName: String, jsonFactory: JsonFactory): ObjectMapper = {
195
val mapper = JsonMapper.builder(jsonFactory).build()
196
// Add custom configuration
197
mapper.configure(SerializationFeature.INDENT_OUTPUT, true)
198
mapper
199
}
200
201
override def overrideConfiguredModules(bindingName: String, configuredModules: immutable.Seq[Module]): immutable.Seq[Module] = {
202
// Add a custom module
203
configuredModules :+ new MyCustomJacksonModule()
204
}
205
}
206
```
207
208
## Factory Setup
209
210
### JacksonObjectMapperProviderSetup
211
212
To use a custom factory, provide it during ActorSystem creation:
213
214
```scala { .api }
215
/**
216
* Setup for defining a custom JacksonObjectMapperFactory.
217
*/
218
final class JacksonObjectMapperProviderSetup(val factory: JacksonObjectMapperFactory) extends Setup
219
220
object JacksonObjectMapperProviderSetup {
221
/**
222
* Create setup with custom factory (Scala API).
223
*
224
* @param factory custom JacksonObjectMapperFactory
225
* @return setup instance for ActorSystem
226
*/
227
def apply(factory: JacksonObjectMapperFactory): JacksonObjectMapperProviderSetup
228
229
/**
230
* Create setup with custom factory (Java API).
231
*
232
* @param factory custom JacksonObjectMapperFactory
233
* @return setup instance for ActorSystem
234
*/
235
def create(factory: JacksonObjectMapperFactory): JacksonObjectMapperProviderSetup
236
}
237
```
238
239
### Using Custom Factory
240
241
```scala
242
import akka.actor.ActorSystem
243
import akka.actor.setup.ActorSystemSetup
244
import akka.serialization.jackson.{JacksonObjectMapperProviderSetup, JacksonObjectMapperFactory}
245
246
val customFactory = new MyCustomFactory()
247
val setup = JacksonObjectMapperProviderSetup(customFactory)
248
val actorSystemSetup = ActorSystemSetup(setup)
249
val system = ActorSystem("MySystem", actorSystemSetup)
250
```
251
252
## Configuration Integration
253
254
The ObjectMapper provider integrates with Akka configuration system, reading settings from `akka.serialization.jackson` section:
255
256
### Binding-Specific Configuration
257
258
```hocon
259
akka.serialization.jackson {
260
# Global settings
261
jackson-modules += "com.example.MyModule"
262
263
# Binding-specific settings
264
my-json-binding {
265
serialization-features {
266
INDENT_OUTPUT = on
267
}
268
}
269
270
my-cbor-binding {
271
compression {
272
algorithm = lz4
273
compress-larger-than = 1 KiB
274
}
275
}
276
}
277
```
278
279
### Accessing Binding Configuration
280
281
```scala
282
import akka.serialization.jackson.JacksonObjectMapperProvider
283
284
val config = JacksonObjectMapperProvider.configForBinding("my-binding", system.settings.config)
285
val isCompressionEnabled = config.getString("compression.algorithm") != "off"
286
```
287
288
## Best Practices
289
290
1. **Use `getOrCreate()` for shared mappers** - Reuses configured instances for better performance
291
2. **Use `create()` for specialized mappers** - When you need mapper-specific customizations
292
3. **Don't modify returned ObjectMappers** - They may be shared across threads
293
4. **Use binding names consistently** - Match names used in serialization-bindings configuration
294
5. **Configure features through setup or configuration** - Avoid runtime ObjectMapper modifications
295
6. **Cache factory instances** - Custom factories can be expensive to create