In my project i used a lot com.fasterxml.jackson.databind.ObjectMapper to deal with JSON, for example:
ObjectMapper mapper = new ObjectMapper();
A a = mapper.readValue(file.getBytes(), A.class);
At first sight I think it's better it's better to make the readValue method static, then we can use it as ObjectMapper.readValue(), much more clear. But I know there must be some reasons that it shouldn't, does anyone know it?
Other reason is with each instance of ObjectMapper you bind certain specific confuguration ready by ObjectMapper while serialization and desrialization process somethinglike below.
So you can configure different startegies while object conversion process.
ObjectMapper mapper = new ObjectMapper();
mapper.configure(DeserializationConfig.Feature.FAIL_ON_UNKNOWN_PROPERTIES, false);
String json = mapper.writeValueAsString(new MyBean());
Related
We have a Spring based application and we have defined a singleton bean for Jackson ObjectMapper class.
#Bean(name = "jacksonObjectMapper")
public ObjectMapper createObjectMapper() {
return new ObjectMapper();
}
We have a use case to write a generic JSON Serializer/Deserializer which we wrote in following way:
public <T, U> T deserialize(final String inputJsonString, final Class<T> targetType, final Class<U> targetParameterType) throws JsonProcessingException, IOException {
return objectMapper
.reader(objectMapper.getTypeFactory().constructParametricType(targetType, targetParameterType))
.without(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES)
.readValue(inputJsonString);
}
Here I am using ObjectReader instead of ObjectMapper itself and changing some configurations on ObjectReader (e.g. .without(...)). My question is, will such configuration changes impact other threads which may be using the same ObjectMapper instance to do something else (may be simply deserializing or serializing)?
Could someone help me understand the details and guide me?
My apologies if I haven't explained the question clearly; please let me know and I can provide further details.
Short answer: No, ObjectReader configuration does not change the underlying ObjectMapper configuration.
Explanation: If you use the ObjectMapper directly and alter the configuration of the mapper it can lead to problems if the mapper is shared between multiple threads. However, if you do not change the underlying config you should be safe anyway (more reading here).
In your case you are calling the mapper.reader(...) method where you actually create an ObjectReader. The ObjectReader and ObjectWriter are immutable and therefore they never change the underlying state. Furthermore, even if you change the config of the underlying ObjectMapper the reader will not be affected.
Note that for each call to the mapper.reader(...) method you are creating a new ObjectReader so if you change your ObjectMapper config between calls to the reader method you may run into problems.
So, to summarize: If you create an ObjectReader and use the same reader in your thread you are safe.
I need to serialize my POJO object that relies on JAXB annotations. I can easily do this with Jackson (adding JaxbAnnotationIntrospector). Is possible without any explicit coding?
It would be really nice to write it fluently akin to this:
port(Integer.valueOf(port)).
log().all().
contentType(ContentType.JSON).
body(criteria, ObjectMapperType.JACKSON_2)
Yet this one ignores JAXB. I want to find some neat and clean solution. Jackson + JAXB is very common practice, it will be such a shame if RestAssured is not equipped with it under the hood. I found something like this on the forum:
RestAssured.config = RestAssuredConfig.config().objectMapperConfig(new ObjectMapperConfig().jackson2ObjectMapperFactory(
new Jackson2ObjectMapperFactory() {
#Override
public ObjectMapper create(Class aClass, String s) {
FilterProvider filter = new SimpleFilterProvider().addFilter(...);
ObjectMapper objectMapper = new ObjectMapper();
objectMapper.setFilters(filter);
return objectMapper;
}
}
));
but this will be my last resort.
If this is a common use case please add it as an issue and I'll try to integrate it as default.
Needed to have support for Scala Lists and Options when storing to Riak. Looks like the Scala Module for Jackson would work for this. However, how would it be hooked into the object mapper in Riak? Not sure if I need to override something or if there's an annotation that can easily solve it.
https://github.com/FasterXML/jackson-module-scala
A few releases ago I added a getObjectMapper() method to the JSONConverter as someone had requested it. This is the Converter that is used for fetch/store operations if you're passing in POJOs and haven't created and passed in your own.
You'd want to instantiate the JSONConverter yourself and get the ObjectMapper from it:
JsonConverter<MyClass> converter = new JSONConverter<MyClass>(MyClass.class, bucketName);
ObjectMapper om = converter.getObjectMapper();
You can now register the module with the ObjectMapper and then use the JSONConverter with your fetch/store operations (using the withConverter() method of the StoreObject and FetchObject).
I think that's what you're looking for. If you needed more control over serializing/deserializing your objects you could also write your own Converter- I've written a cookbook entry on the subject here: https://github.com/basho/riak-java-client/wiki/Using-a-custom-Converter
Currently we are using Jackson 1.9.x in our application and have following code:
Object objectMapper = new ObjectMapper();
.....
SerializationConfig config = getConfig();
objectMapper.writeValue(jg, value, config);
As I understand during investigation (see SerializationConfig) in Jackson 2.0 (de)serialziation was changed and cannot be attached directly to objectMapper and my question is: What is correct replacment for the last sentence in code snippet?
Thanks in advance.
Usually you would create an ObjectWriter, and reconfigure that if necessary:
ObjectWriter w = mapper.writer(....); // various configuration methods
w.writeValue(jg, value);
Underlying configuration objects are hidden on purpose, as ObjectReader and ObjectWriter are immutable and thread-safe, so you can share and pass those instead of config objects.
i have a task serializing a class like RPC message to JSON
using Jackson in Java. I have to say that i´m a complete newbie to Jackson.
Now what i´m trying to do is to serialize array type into JSON.
I have:
ObjectMapper mapper = new ObjectMapper();
a message is then put into HashMap (simplified)
LinkedHashMap<String,Object> map = new LinkedHashMap<String, Object>();
if(msg.getSignal())
map.put("signal",msg.getMethodName());
else {
map.put("method", msg.getMethodName());
map.put("retT", msg.getReturnType()); //returns Class<?> type
}
return mapper.writeValueAsString(wrapper);
for method name "add" and return type int[], this results in:
{"method":"add","retT":"[I"}
Can anyhone please help me how to achieve "[int]" instead of "[I"?
I assume that 'msg.getReturnType()' returns Class; and if so, Jackson will just call toString() on it. If so, you would want to instead do conversion yourself, to get actual String value you want.
You can also simplify code a bit, since ObjectMapper has 'writeValueAsString()' method:
return mapper.writeValueAsString(wrapper);
which will internally handle creation of StringWriter and JsonGenerator, to achieve what you are doing.