How to write java map to csv with jackson? - csv

I am using jackson-dataformat-csv.
I have a pojo which contains a java.util.Map. I know jackson does not support writing a map to csv directly, but is there any workaround? Basically i have semi-random key-value pairs which i need to write to csv. Can i do it manually somehow?

I don't think so.
I've also looked and can't find anything. It's too bad, too, since it would be trivial to do the equivalent of flattening out the map and bringing it up to the top level.
Optionally, it could prefix the name of the map (specified by #JsonProperty) to prevent heading name collisions.
So a class with these members:
#JsonProperty("Name") String firstColumn = "Bart";
#JsonProperty("FamilyMember") Map family = ImmutableMap.of(
"Dad", "Homer",
"Mom", "Marge");
could output like:
Name, FamilyMember.Dad, FamilyMember.Mom
Bart, Homer, Marge
Someone (#taivo) should contribute that!
But if you don't have time, you are probably better off just writing your own mapper to flatten the map into a pojo..

Related

Using Jolt, How do I remove a field "last_update" from everywhere in a JSON string?

I have a JSON array of objects and in many of the objects, at various points, there's a "last_update" field. ("Person" object may have a "Jobs" array and each Job in Jobs array may have an last_update, as well as the parent Person, as well as each Address in the "Addresses" object, etc. The "last_updated" field is not always at the same depth for various objects and in some objects may appear in multiple places.
I want to remove any mention of "last_update" no matter where in the JSON tree it lands.
If I was editing the JSON in Vim, I'd probably try using something like s/last_updated.*?//g.
It does not have OOTB support for that.

Should the structure of a derived obj file coinside with the naming of the original step file?

When using the Model Derivative API I successfully generate an obj representation from a step file. But within that process are some quirks that I do not fully understand:
The Post job has a output.advanced.exportFileStructure property which can be set to "multiple" and a output.advanced.objectIds property which lets you specify the which parts of the model you would like to extract. From the little that the documentation states, I would expect to receive one obj file per requested objectid. Which from my experience is not the case. So does this only work for compressed files like .iam and .ipt?
Well, anyway, instead I get one obj file for all objectIds with one polygon group per objectId. The groups are named (duh!), so I would expect them to be named like their objectId but it seams like the numbers are assigned in a random way. So how should I actually map an objectId to its corresponding 3d part? Is there any way to link the information from GET :urn/metadata/:guid/properties back to their objects?
I hope somebody can shine light on this. If you need more information I can provide you with the original step file, the obj and my server log.
You misunderstood the objectIds property of the derivatives API: specifying that field allows you to export only specific components to a single obj, for example your car model has 1000 different components, but you just want to export components that represent the engine: [34, 56, 76] (I just made those up...). If you want to export each objectId to a separate obj file, you need to fire multiple jobs. the "exportFileStructure" option only applies to composite designs (i.e. assemblies) single: creates one OBJ file for all the input files (assembly file), multiple: creates a separate OBJ file for each object. A step file is not a composite design.
As you noticed the obj groups are named randomly. As far as I know there is no easy reliable way to map a component in the obj file to the original objectId because .obj is a very basic format and it doesn't support metadata. You could use a geometric approach (finding where is the component in space, use bounding boxes, ...) to achieve the mapping but it could be challenging with complex models.

Deserialize an anonymous JSON array?

I got an anonymous array which I want to deserialize, here the example of the first array object
[
{ "time":"08:55:54",
"date":"2016-05-27",
"timestamp":1464332154807,
"level":3,
"message":"registerResourcePath ('', '/sap/bc/ui5_ui5/ui2/ushell/resources/')",
"details":"","component":"sap.ui.ModuleSystem"},
{"time":"08:55:54","date":"2016-05-27","timestamp":1464332154808,"level":3,"message":"URL prefixes set to:","details":"","component":"sap.ui.ModuleSystem"},
{"time":"08:55:54","date":"2016-05-27","timestamp":1464332154808,"level":3,"message":" (default) : /sap/bc/ui5_ui5/ui2/ushell/resources/","details":"","component":"sap.ui.ModuleSystem"}
]
I tried deserializing using CL_TREX_JSON_SERIALIZER, but it is corrupt and does not work with my JSON, here is why
Then I tried /UI2/CL_JSON, but it needs a "structure" that perfectly fits the object given by the JSON Object. "Structure" means in my case an internal table of objects with the attributes time, date, timestamp, level, messageanddetails. And there was the problem: it does not properly handle references and uses class description to describe the field assigned to the field-symbol. Since I can not have a list of objects but only a list of references to objects that solution also doesn't works.
As a third attempt I tried with the CALL TRANSFORMATION as described by Horst Keller, but with this method I was not able to read in an anonymous array, and here is why
My major points:
I do not want to change the JSON, since that is what I get from sap.ui.log
I prefere to use built-in functionality and not a thirdparty framework
Your problem comes out not from the anonymity of array, but from the awkwardness of SAP JSON (De)serializer, which doesn't respect double quotes, which enclose JSON attributes. The issue is thoroughly described in this answer.
If you don't want to change your JSON on-the-fly, the only way you have is to change CL_TREX_JSON_DESERIALIZER class like this.
/UI5/CL_JSON_PARSER parses JSONs with unknown format.
Note that it's got "for internal use" written on it so many times that you probably should take it seriously and clone its code to fixate it.

If JSON represents the 'object', what represents the 'class'?

JSON appears to be a nice way to represent a complex data structure in plain text. If we think of this complex data structure as analogous to an OOP object - an instance of a class - then is there a commonly used JSON-like format that represents the class itself (just the data part - forget methods)? Can JSON itself be used for this?
To put it another way, if JSON encodes name-value pairs, what should I use if I want to encode only the names?
The reason I want this is that I am designing a protocol to use with jQuery (to which I am a complete novice by the way). The client will communicate to the server the structure of the JSON object it wants back, and the server will return a JSON object of that structure with the values added.
The key point is that it is the client that is in full control of what data fields (name-value pairs) the server returns. It's a bit different from all the examples of jQuery that I've found so far on the web where the client makes a request (which usually includes a very limited set of parameters, if any) and the server makes the decision as to what fields to return in the JSON reply.
(Obviously, what the client asks for must be congruent with the server's data model; if the server has an array of widgets each with its own price, the client can't ask for an array of prices each with its own widget.)
This must be a common problem, and I don't want to reinvent the wheel. I want to adopt a solution that is already in common use across the web.
Edit
I just found JSON Schema. This is not what I am looking for. It contains way more than I need.
Edit
I'm looking more for a 'this is how it is usually done' answer, rather than a 'you could try…' answer. (I can invent dozens of possible answers myself.)
To encode only names within JSON, you could use a key/value pair where the key is either the class name or just a key named 'values' - with the value being an array of strings that are the names to be returned by the server. For example:
{ 'class_name' : [ "name1", "name2", "name3" ] }
The server can then either detect the class name from the key used and return the supplied values for the names in the array if the class supports it or ignore if it does not.
I'm looking more for a 'this is how it is usually done' answer
There is no single "correct" way to do what you want. Many people have their implementation. It depends on various factors -- what you want to do, where you want to do, how efficiently you want it to do?
For simple structures I would prefer and suggest the answer given by #dbr9979.
For nested structures, you can have nested arrays. Something like:
{
"nestedfield1": {
"nestedfield11":["nestedfield111", "nestedfield112"],
"nestedfield12":["nestedfield121", "nestedfield122"],
"__SIMPLE_FIELDS__": ["simplefield13", "simplefield14"]
}
}
The point is, if the key is __SIMPLE_FIELDS__, the value is an array of simple fields (string, numbers etc..), else the key stands for the key in the object.
For something more complex, what I would suggest is you have predefined structures, that both the server and the client know of. This is particularly useful when you have to make multiple identical requests. Assign some unique number for each of them. Something like:
1 => <the structure above>
2 => ["simplefield1", "simplefield2" ..]
3 => etc .. etc
The server stores the above structure and the relevant number in the database or something. And now, as it may be obvious by now, client sends across the id of the required structure, and the server responds in the appropriate fashion.
I think what you meant by this:
the client that is in full control of what data fields (name-value pairs) the server returns.
is like the difference between SELECT * FROM Bags and SELECT color, price FROM Bag in SQL. Am I interpreting you correctly?
You could query with:
{
'resource': 'Bag',
'field_names': ['color', 'price']
}
which will return the response:
{
'status': 'success',
'result': [
{'color': 'red', 'price': 50},
{'color': 'blue', 'price': 45},
]
}
most likely though, you may not actually need your request to be a JSON object; I've seen implementations where the field names is taken from the query string, like http://foo.com/bag?fields=color,price
I was looking for Partial Response.
RESTful API Design: can your API give developers just the information they need? explains it all and gives examples from LinkedIn, Facebook, and Google. Google and Facebook both have similar approaches. Here's how Lie Ryan's example would look using Google's approach:
url?fields=status,result(color,price)
Since Google and Facebook are behind this, I would not be surprised to see this become a de facto standard.
In my case I am likely to run into a length limitation on the URL and so have to use POST instead, but this is an excellent starting point for me.

Serialized JSON with sorted keys, using Jackson

I'm trying to replace a custom JSON (de)serialization in a groovy/grails project with Jackson.
I'm having trouble getting Jackson to output a pretty-printed JSON with keys sorted in a simple 'natural' alphabetic order.
I've tried this (and many variations):
mymap = [ ... ] // Some groovy map
def mapper = new ObjectMapper()
mapper.configure(SerializationConfig.Feature.SORT_PROPERTIES_ALPHABETICALLY, true)
def jsonstring = mapper.defaultPrettyPrintingWriter().writeValueAsString(mymap)
But Jackson stubbornly generates a JSON where the keys seem to be in a random order.
I've tried changing the type of 'mymap' with a TreeMap, and in that case all keys are properly sorted as expected.
I'm wondering if there is a way to get the keys sorted without changing 'mymap' above to a TreeMap (and recursively all of its map values...).
SORT_PROPERTIES_ALPHABETICALLY seems to be intended to do precisely that, but it's not doing it for some reason.
Would you know why that is? Anything I'm doing wrong above?
I've tried with Jackson 1.8.3, 1.8.8 and 1.9.5, same result (random keys).
As stated by #tim_yates, this doesn't work for map keys.
You could use
mapper.configure(SerializationConfig.Feature.ORDER_MAP_ENTRIES_BY_KEYS, true)
With newer version ( >= 2.6.1) the API changed to:
mapper.configure(SerializationFeature.ORDER_MAP_ENTRIES_BY_KEYS, true);
The documentation for SORT_PROPERTIES_ALPHABETICALLY explicitly says:
Feature that defines default property serialization order used for POJO fields (note: does not apply to Map serialization!)
So I guess you will need to change your input Map (as you say)
As pointed out, this feature just works for POJOs. However, I think there is a feature request to do the same for Maps, at Jackson Jira; and if not, this sounds like a good addition.
But in the meantime I would second #tim_yates suggestion to use intermediate TreeMap for sorting, serializing that: ordering that Map has will be used as is, so this should work.