Create list of custom objects from flat JSON data - json

I want to create an arraylist of type Adapter from a JSON. But since the JSON is not in arraylist format, I'm unable to use gson.fromJson() method.
Is there any way by which I can create a list of my custom object by parsing the following JSON?
JSON data:
"source":{"adapter-config.adapter[0].name":"testAdapter1",
"adapter-config.adapter[0].resolverName":"serviceResolver",
"adapter-config.adapter[0].parameters[0].key":"serviceId",
"adapter-config.adapter[0].parameters[0].value":"serviceIdPathInEvent",
"adapter-config.adapter[0].parameters[1].key":"appId",
"adapter-config.adapter[0].parameters[1].value":"appIdPathEvent",
"adapter-config.adapter[0].parameters[2].key":"env",
"adapter-config.adapter[0].parameters[2].value":"envPathInEvnet"}
My Adapter Object:
public class Adapter {
private String name;
private String resolverName;
private List<KeyValuePair<String, String>> attributeList;
}

Gson does not provide such functionality out of the box. However you can achieve this by manually reading the JSON data from a JsonReader, consuming the JSON property names with nextName() and then parsing them to determine which data they represent. You could either directly read from a JsonReader, or in case the shown JSON data is only an extract from a larger JSON document, you can implement a TypeAdapter for your List<Adapter>. That TypeAdapter could then either be registered with a GsonBuilder by providing new TypeToken<List<Adapter>>() {}.getType() as type, or you could annotate the field holding the List<Adapter> with #JsonAdapter.
For the actual parsing of List<Adapter>, I would recommend storing a current adapter (and its index in the list) in a local variable. Whenever you parse a JSON property name, you could then check if the index encoded in the name is equal to the index of the current adapter, then you are going to modify the existing instance, otherwise if the encoded index is equal to the index of the current adapter + 1 you create a new Adapter instance, add it to the list of adapters and reassign the current adapter variable and its index variable. Then you continue with parsing the remainder of the property name to find out which Adapter field values to set.
(In case you get stuck there, feel free to let me know in the comments and I can try to provide some concrete code; but it would probably be best if you tried it yourself first.)

Related

Why an ArrayList Type of the object does not support the size() method which is a builtin method for the ArrayList Type Object?

The entire question is in java. I am trying to extract some information from a json data format, then I used an mapper object to
data = mapper.readValue(jsonData, new TypeReference<>(){});
to convert this into a List of HashMaps, in fact, printing data.get(0).getClass() gives me as an LinkedHashMap, when I run data.get(0).get("key") returns as an ArrayList, but when I do ```
data.get(0).get("key").size()
It complains, can anyone point out why and provide me any suggestion on how to get the associated values from the key?

Serialize/deserialize a Dictionary with a comma-separated entry

I am developing a ASP.NET Core 3.1 website and I have data in a Dictionary<string, object> that I want to Serialize/Deserialize using Microsoft System.Text.Json (I am new to Json serialize/deserialize in fact). The data comes from a PostgreSQL DB query and one of the returned values is a comma-separated list of integers (converted to string) that results from the STRING_AGG function. The image below shows one of the entries of the Dictionary:
I serialize it using the following code. Please note that I have tried both Microsoft System.Text.Json and Newtonsoft.
jsonResult = Newtonsoft.Json.JsonConvert.SerializeObject(result);
//jsonResult = JsonSerializer.Serialize(result);
The data in the Dictionary should be deserialized according to the following class structure:
I use the following code:
//IEnumerable<SeccGralContenidoViewModel> seccGralContenido = JsonSerializer.Deserialize<IEnumerable<SeccGralContenidoViewModel>>(_seccGralContenidoRepository.Read());
IEnumerable<SeccGralContenidoViewModel> seccGralContenido = Newtonsoft.Json.JsonConvert.DeserializeObject <IEnumerable<SeccGralContenidoViewModel>>(_seccGralContenidoRepository.Read());
However, an exception is thrown when deserializing no matter if I use Newtonsoft or System.Text.Json:
I am originally using System.Text.Json namespace but I also tried using Newtonsoft. After analyzing a bit deeper, I see that the problem could be the way in which data is saved to the Dictionary but I have not found a workaround.
If you don't want to write a custom converter then the simplest solution is to introduce another property:
public string CategoriasContenidolds {get; set;}
private static char delimiter = ',';
[JsonIgnore]
public string[] CategoriasContenidolds_Collection
{
get => CategoriasContenidolds.Split(delimiter).Select(item => item.Trim()).ToArray();
set => CategoriasContenidolds = string.Join(delimiter, value);
}
The serializer will use the CategoriasContenidolds property during serialization and deserialization
You should use CategoriasContenidolds_Collection (or name whatever you want) in your business logic
By explicitly marking this property with JsonIgnore the serializer will ignore that
I could solve my issue by directly getting JSON formatted results from queries. PostgreSQL does an excellent job. This way I also avoid performing a 2-step process: first, getting the query result; second, serializing to JSON.

How to catch remainder of JSON data that didn't match any POCO properties while using Elasticsearch Nest client and Utf8Json serializer

I'm using the C# Elastic Nest client to retrieve the data from the Elasticsearch. I have created a POCO class named IndexModel which corresponds to the index mapping of my "testing-index" index. I get all the data from the index using this search method:
var result = client.Search<IndexModel>(s => s
.Index("testing-index")
.MatchAll());
However, I would like to be able to gather also the json data that didn't succeed to be mapped into any of the POCO properties, e.g. when the index mapping changes. I know that Nest uses Utf8Json as a Json serializer, but I couldn't find out if there is a possibility like in System.Text.Json.Serialization to add a data annotation above some dictionary that would catch all the overflow json data. Something like this?
[JsonExtensionData]
public Dictionary<string, object> ExtensionData { get; set; }
Or is there a possibility that the elastic client handles it and informs me somehow that some data didn't match any POCO properties?
There's no feature for this in the client.
The options are defining a POCO to represent the document, or using a type that can handle arbitrary JSON structures such as using JsonNetSerializer along with JObject to represent documents.

Can Hibernate automatically map a HashMap to a string column?

I have a HashMap which was populated from form elements of an HTML page, and when I save it I need Hibernate to convert it automatically to a JSON string and also persist it as a JSON string. Is this doable in Hibernate? Or, can you tell Hibernate in the mapping file (or maybe, as an annotation) to call a Java method that converts HashMap to JSON, and persist the return value of that method, and vice-versa? (read JSON string and convert automatically to a HashMap).
Thanks for all the help!
Sure, you can just create a custom user type:
http://docs.jboss.org/hibernate/orm/3.6/reference/en-US/html/types.html#types-custom
Hibernate will then use this to persist data to the database, and to read it back as object.

Convert JSON formated String to JsonObject with Jayrock

I have a request parameter in my ASP.NET app. that is in JSON format, and I was wondering if there is a good (quick and easy) way to convert a JSON string to a Jayrocks JsonObject, so I can easily extract key-value pairs without the need to manually parse the string?
Assuming json is the variable containing JSON text, use Jayrock.Json.Conversion.JsonConvert.Import(json). What you will get back in return is either a JsonObject, JsonArray, JsonNumber, System.String, System.Boolean or a null reference depending on the root JSON value in the source JSON text. If you know it is going to be a JSON object for sure then you can safely cast the return value or use JsonConvert.Import<JsonObject>(json).
I would discourage working against JsonObject directly unless you particularly depend on one of its features. You should just pretend the JSON object you get back is a dictionary; either IDictionary or IDictionary<string, object>. With the latest version for .NET Framework 4, you can also work with a JsonObject as a dynamic object.
I don't know Jayrock, but if you want to accept a JSON object as a parameter of Action in MVC2 than the easiest way to do it is by using JsonValueProviderFactory from Futures assembly.
It's part of System.Web.Mvc in MVC3.