I have some code that pulls data from a DB and populates a POJO. That POJO then gets serialized and pushed into an elasticsearch cluster.
The problem I am having is that one of the fields in the database was free text and people just put in a to get around the required field.
I'd like to be able to strip that whitespace out when pushing to elastic.
Here's an example of my pojo
public class Destination {
Long id;
...
...
String Address;
}
I am using Jackson to turn this into JSON using the ObjectMapper class. ie
mapper.convertTo(dest, Map.class)
When I view the value in elastic I am seeing:
{"id":1, ..., "address": " "}
Ideally, in this case, I'd just like to see the "id" property since the "address" is essentially null.
I've tried using ObjectMapper's serialization properties, but nothing seems to be working. Is there a standard way that this is being handled? How does Spring handle this?
I've seen similar questions asked (Jackson Json Serialization : Remove Blank strings), but I'm not sure how to apply that solution globally, rather than just at the class level, or if you can apply it globally.
Related
Let's say we have following JSON,
{
"id": "imgsId1",
"type": "Fruits",
"name": "Tropical",
"image":
{
"url": "images/img1.jpg",
"width": 300,
"height": 300
},
"thumbnail":
{
"url": "images/thumbnails/img11.jpg",
"width": 50,
"height": 50
}
}
And in Java Class, we have all fields matching with above JSON.
Each time list of fields to be Deserialized depends on customer who sends the information.
For example for customer 1, we want to only read back following values, (and skip other properties even if provided in JSON)
String[] propertiesToFilter1 = {"type","image.url"};
For example for customer 2, we want to read back following values, (and skip other properties even if provided in JSON)
String[] propertiesToFilter2 = {"type","image.url", "image.width"};
When Deserializing JSON using Jackson, is it possible to provide above array which includes which fields need to be Deserialized,
ImageInfo obj1 = (ImageInfo)objectMapper.readValue(jsonStr, ImageInfo.class);
Update:
On researching on net, i saw that one of the options could be via using
FilterProvider filterProvider = new SimpleFilterProvider().addFilter("filterName1",
SimpleBeanPropertyFilter.serializeAllExcept(propertiesToFilter1));
objectMapper.setFilters(filterProvider);
But i think this is good, if we want to keep reusing the same "filterName1" for multiple customers.
In this scenario, it's little bit different because, we customize list of fields each customer can update. So each customer has different list of JSON fields they can update in different classes.
If we start defining different filter names for each customer, it will be a long list, and lookup will have performance impact.
So was looking for solution, where i can check list of fields allowed to be processed at runtime, when constructing back object using objectMapper.readValue() method.
Update 2 (Apr 25 2016):
Going through other Jackson questions, saw a similar question here,
Jackson Dynamic filtering of properties during deserialization
Using the approach listed below by creating custom "static ObjectMapper", the issue with this approach is we running Reflection API multiple times.
First time Jackson parser is populating all fields using
Reflection API when Deserializing JSON to Java Object
Second time, since we can't take all fields that were populated by
Jackson parser, for populate data into another object, we again need to run through Reflection API to populate another object.
This could result in lot of overhead.
Using the approach defined in above link provided, i think using "BeanDeserializerModifier" seems to be best approach. Now the question is, since we are also using Factory based approach to initialize ObjectMapper, we don't want to hard code all arrays for different customers.
Wanted to check if it's possible to provide the String[] array with list of Properties to be considered at runtime to "BeanDeserializerModifier"?
something similar to,
String[] propertiesToFilter2 = {"type","image.url", "image.width"};
BeanDeserializerModifier curBeanDeserializerModifier =
getBeanDeserializerModifierInstance();
curBeanDeserializerModifier.setPropertiesToConsider(propertiesToFilter2);
Thanks
use #JsonIgnoreProperties with configure parameters
http://www.programcreek.com/java-api-examples/index.php?api=com.fasterxml.jackson.annotation.JsonIgnoreProperties
I am not sure if there is a possibility to configure the deserialization dynamically with annotations.
I would suggest to create a class with a static ObjectMapper. In this class you can create different implementations of deserialization. The business logic of your application should then decide which implementation should be used for which customer. Inside your different implementations you are able to configure the ObjectMapper like you do it with annotations.
A second solution can be to deserialize the full json for every customer and let the business logic decide which fields/objects of the Pojo is used. This needs also an implementation in your application.
The benefit of the implementation of the configuration in the business logic is that you will have cleaner code and one place where your configuration is done for every customer.
static ObjectMapper information
I have a RESTful web service that provides JSON that I am consuming. I am using Spring 3.2 and Spring's MappingJacksonHttpMessageConverter. My JSON looks like this:
{
"Daives": {
"Daive": {},
"Daive": {},
"Daive": {},
"Daive": {}
}
}
Now everything I have read seems to indicate that this JSON should be refactored to an array of JSON Daives. However, this is valid JSON so I want to make sure that I am thinking correctly before going back to the service provider to ask for changes. In the format above, I would have to know ahead of time how many Daives there are going to be such that my DTO accounted for them. The handy dandy Jackson mapper isn't going work with this kind of JSON setup. If the JSON was altered to provide and Array of JSON Daives, I could use a List to dynamically map them using Spring/Jackson.
Am I correct? Thanks :)
According to this thread, the JSON spec itself does not forbid multiple fields with the same name (in your case, multiple fields named "Daive" in the object "Daives").
However, most parsers will either return an error or ignore any value but the last one. As you said, putting these values into an array seems much more sensible; and indeed, you'll be able to map this array to a List with Jackson.
I have a bean with an arbitrary JsonValue property which I need to marshal/unmarshal from JSON.
public class MyBean {
public String name;
public JsonValue data;
}
Since JsonValue is the standard javax.json.JsonValue, I was expecting MOXy to marshal/unmarshal it out of the box, instead I got a plain string:
{
"name": "foo",
"data": "{\"some\":\"json\"}"
}
where I was expecting this:
{
"name": "foo",
"data": {
"some": "json"
}
}
When unmarshalling, data becomes null. How can I use JsonValues and get MOXy manage them like expected?
(I need to stick with default Jersey/MOXy, so no use of other libraries.)
Note: this is not an answer (solution for the OP). I typed it out before I read "I need to stick with default Jersey/MOXy". Was going to change to a comment, but there's too much stuff. I'll just leave it up for future readers.
There is a different provider for the javax.json classes. MOXy doesn't know how to handle them the way you expect. Without looking at any source code I would guess that what you are seeing is the value of toString() from the JsonValue instance. This is what will happen if the type can't be handled. You'll just get a toString() call.
Even if you add the dependency I linked to, you still have the problem that different providers don't interact with each other. What would need to happen is that in the middle of MOXy serializing the MyBean instance, if it sees a javax.json object, it tries to look for a different provider to handle it. It just doesn't work like that. Only one provider will be used.
The only solution I can think of is to instead of using MOXy, use Jackson, which has a module that supports javax.json. If you register that module with Jackson, it will know how to handle the javax.json types, "mid-serialization". You can have a look at this answer, which describes the step you should take to make it work with Jackson.
I am trying to implement struts2-jquery-grid. But I am stuck with the serialization issue. I can't find out really what is mean by serialization in struts2 type="json". I have checked the struts website documentation but that is not clear to me. Anyone please tell me in simple words what is struts serialization?
The output of whatever object will be serialized into JSON format and returned to the client (web browser mostly in this case).
For example, if a class like such would to be returned in JSON:
class Person{
private int age;
private String name;
// omitted getter and setter
}
Its corresponding JSON return String will be: (values are mocked up and assumed)
{"person1": {"age": "2", "name": "Chin Boon"}}
serialization is the process of converting a data structure or object state into a format that can be stored (for example, in a file or memory buffer, or transmitted across a network connection link) and "resurrected" later in the same or another computer environment.
So JSON plugin is converting your whole object graph, starting on the action class and will send the data to the UI where the JSON data can be used for UI display and same process can be used in reverse order.
Concept of serialization is not specific to Struts2 its a generic concept and is used a lot in real life application
When playing with REST, my provider is generating JSON with attribute names starting with an at sign when the property is marked as #XmlAttibute like this:
#XmlAttribute
int foo = 1;
will return
{"#foo":1}
How can I tell Jackson for deserializing that if I have on the client
int foo;
that it should take the json-Attribute #foo for this. Or in more general terms: how to tell Jackson to ignore the # when deserializing?
Update: I know about #JsonProperty("#foo") annotation that StaxMan is referring - I forgot to put that in my original question, as I was especially interested in a "global setting" and not on a per property level.
Easiesti thing might be to disable adding those '#' signs there as they seem useless. I know some XML-to-JSON libs (Jettison) want to use this to differentiate between XML attributes and elements, but it's of little use with actual JSON processing.
But Jackson can be given expected property name in JSON with #JsonProperty annotation:
#JsonProperty("#foo")
public int foo; // or add in setter
if it is necessary to keep those at signs in there.
I think you want #XmlElement rather than #XmlAttribute. Values for the latter are always given a # at the beginning.