Spray JSON - deserialize field that may have different values - json

I am facing a problem of parsing a JSON with a field that may be Array or single object. In case hotel has multiple rooms, typical JsArray is returned. However, if it has only one type of room, it returns only one single object.
I am trying to parse this situation using case classes, especially List[Room] for this situation. This however fails in case only one single object is returned. Is there a way how to overcome this with case classes? If not, what is the solution to this problem?
Thank you very much.

You can use Either[A,B], Either can contain either instance of A or instance of B
case class Hotel(data: Either[Room, List[Room]])

Related

Freemarker: find specific object in array of arrays

I have a complex many-to-many relationship defined. The cross-reference table is an entity, so I have Contact with a One-To-Many to ContactList, and List with a One-To-Many to Contact List. Contact List contains listID, contactID, and a few Booleans. The relationships seem to work well and on the backend I can get a list of contacts on a review list using the Spring-Data-Jpa findByContactListsIn(Set).
However, I am trying to build a list of contacts in Freemarker, and show whether they were in the current list.
Before I made an Entity out of ContactList, I had a standard Many-To-Many relationship between them, and I was able to do something like this in my .ftl:
<#if list.contacts?seq_contains(contact)>
But I needed to add some data to ContactList specifically, so I needed it to be more complicated. How can I do something similar now? I tried:
<#if list.contactLists?seq_contains(contact)
But of course that always returns false, because it is comparing two different entity types. Is there a way to find if a contact is in one of the contactList objects?
I suppose I could do some back-end trickery, but I am looking for a front-end solution to this.
Don't use ?seq_contains for finding generic object at all. It doesn't call Object.equals, instead it works like the == operator of the template language, which only allows comparing strings, numbers, booleans and dates/times, otherwise it gives you an error. Unfortunately it won't fail in your case, because POJO-s are also strings (and their string value is what toString() returns). This is an unfortunate legacy of the stock ObjectWrapper (scheduled to be fixed in FM3); not even a quirk in the template language. Ideally you get an error there. Instead, now it silently compares the return value of the toString()-s...
Your data-model should already contain what the template should actually display. FTL is not a programming language, so if you try to extract that from the data-model in it, it will be a pain. But, that the data-model contains that data can also mean that some objects in the data-model have methods that extract the data you need. As a last resort, you can add objects that just contain helper methods.
Update: Returning to ?seq_contains, if you need the Java semantics and list is a Java Collection, you can just use the Java API: list?api.contains(contact).

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.

Spray.io - Removing fields from response

I've built a RESTful API using Spray.io.
It contains a number of endpoints, each of which returns JSON.
I use the Spray JSON marshaller to marshal my internal objects to JSON which are returned to the user. So I have something similar to...
respondWithMediaType(`application/json`) {
complete(MyResponse(username, password))
}
Where MyResponse is a case class...
case class MyResponse(username:String, password:String)
However, I want to pick the fields that are returned in the response. So in this case I want to remove the "password" field before it is returned.
Whats the best way to do this with Spray?
Thanks
Posting an answer to close question. Went with Yuvals suggestion above (he didn't add as answer)...
"Why not create PasswordLessResponse case class, instead of jumping hooks to deserialize MyResponse in different ways"
and just created the relevant case classes and marshallers, populated and returned where needed.
Thanks Yuval!

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.

how to WCF dynamic DataMember?

example: a Customer class have 100 data member(id, name, age, address...etc) to be serialization to JSON.
In Config file such as Web.config, can set a output list to serialize JSON ouptut.
If output only id and name, then JSON only have id and name.
My Question: Can support dynamic DataMember in a DataContract ?
You mean optional datamembers, I guess so, check this question
Surely you'll have to have null values for the ones you dont want to send over the wire.
Another, more dirtier, solution would be to use a dictionary as a datamember and have the fields you want to send as elements there. There may be type conversion issues, but maybe it serves you better.
Edit:
You probably want to go with a dictioray serialized as an associative array en js, as this question specifies. Check the answers and the links in there. That should get you going.
But still I'd go with optional datamembers since it's more of a "contract" thing. Other than that a better description of what you want to do will help.