Json .net settings equivalent to JavaScriptSerializer default for dates - json

I am using the JQuery Ganntt plugin and it needs dates formatted in the Unix epoch format. Using Newtonsoft's Json.Net with these settings
JsonSerializerSettings microsoftDateFormatSettings = new JsonSerializerSettings
{
DateFormatHandling = DateFormatHandling.MicrosoftDateFormat
};
return JsonConvert.SerializeObject(headers, microsoftDateFormatSettings);
I get json that looks like the following
[{"desc":"STAT","name":"Status","values":[{"to":"/Date(1357483427000-0500)/","from":"/Date(1354891427000-0500)/","desc":"","label":"Implement","customClass":"ganttBlue","dataObj":{"id":35,"projectId":18705,"updatedById":437996,"updatedByName":"Linda","updated":"/Date(1354891427000-0500)/","statusId":160,"statusDescription":"","status":"Implement"}}]},{"desc":"ASGNTO","name":"Assigned To","values":[{"to":"/Date(1357762454000-0500)/","from":"/Date(1355170454000-0500)/","desc":"Suzy","label":"Suzy","customClass":"ganttRed","dataObj":{"id":55,"projectId":18705,"updatedById":719816,"updatedByName":"Joe","updated":"/Date(1355170454000-0500)/","assignedToId":561260,"assignedToName":"Suzy"}}]}]
The gantt plugin does not like the date with the -500. It wants this, which is generated from using the JavaScriptSerializer
"[{\"desc\":\"STAT\",\"name\":\"Status\",\"values\":[{\"to\":\"\/Date(1357483427000)\/\",\"from\":\"\/Date(1354891427000)\/\",\"description\":\"\",\"label\":\"Implement\",\"customClass\":\"ganttBlue\",\"dataObj\":{\"Id\":35,\"ProjectId\":18705,\"UpdatedById\":437996,\"UpdatedByName\":\"Linda\",\"Updated\":\"\/Date(1354891427000)\/\",\"StatusId\":160,\"StatusDescription\":\"\",\"Status\":\"Implement\"}}]},{\"desc\":\"ASGNTO\",\"name\":\"Assigned To\",\"values\":[{\"to\":\"\/Date(1357762454000)\/\",\"from\":\"\/Date(1355170454000)\/\",\"description\":\"Suzy\",\"label\":\"Suzy\",\"customClass\":\"ganttRed\",\"dataObj\":{\"Id\":55,\"ProjectId\":18705,\"UpdatedById\":719816,\"UpdatedByName\":\"Joe\",\"Updated\":\"\/Date(1355170454000)\/\",\"AssignedToId\":561260,\"AssignedToName\":\"Suzy\"}}]}]"
What would be the proper setting for the Json.Net converter? I want to use Json.net when we move to .net 4.5.

To make it display a date that is like the one produced by JavaScriptSerializer, you have to give two settings:
JsonSerializerSettings serializerSettings = new JsonSerializerSettings()
{
DateFormatHandling = DateFormatHandling.MicrosoftDateFormat,
DateTimeZoneHandling = DateTimeZoneHandling.Utc
};
Using any other type of DateTimeZoneHandling will cause the timezone offset to be put in. (Seems like a bug that Unspecified still puts the offset in.)
However, if you are using local time throughout the system, doing this will shift the dates by your timezone offset when serializing them. Your dates will be off.
The easiest fix for me was to use the default ISO date, set DateTimeZoneHandling to Local, and change the client to parse the ISO date. Otherwise you would need to adjust the dates before serializing or play with your own custom serializer. Neither of those last two seemed worth it to me.

Related

Create list of custom objects from flat JSON data

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.)

How to display Blob /Json data field in Liferay 7.2?

I am using a service builder that is retrieving the form data fine from mysql db. I have a field that has the json data and I tried to map it using object mapper and using com.fasterxml.jackson.databind.ObjectMapper to display the json content. However, the Blob Data is shown as: com.mysql.cj.jdbc.Blob#4ca74f7f
How do I actually get/extract the data from the storing link above? Here is my code snippet:
for (ddmcontent MyTemp : myList) {
System.out.println("Content ID : "+myList.getContentId());
System.out.println("User Blob Data : "+myList.getData());
Blob responseBody =myList.getData();
ObjectMapper objectMapper = new ObjectMapper();
List<ModelData> myDat = objectMapper.readValue((DataInput)
responseBody,objectMapper.getTypeFactory().constructCollectionType
(List.class,ModelData.class));
for (ModelData dt : myDat) {
System.out.println("User Name : "+dt.Name);
System.out.println("Users Email : "+dt.Email);
}
}
Please note, I have defined my ModelData elements as all String.
Any suggestion? What am I missing?
Thanks in advance!
The toString() representation hints at the object's type com.mysql.cj.jdbc.Blob. If you look up its javadoc (or the interface it implements) you'll see the options that you have to decode the contents of the Blob, namely getting an InputStream or a byte[] representation, which you'd have to subject to the correct character set decoding to turn it into a String.
Make sure you nail the character set by testing it with all kinds of Unicode content, so that you don't have to fix badly encoded database content later when your table contains a lot of data in unknown encodings.
As you're using Liferay's Service Builder, you might want to share the relevant parts of your service.xml (optional model-hints.xml) to check for an easier implementation.
I finally got this working by changing the field in question to String and addining a max length to certain number of Char
Thanks!

How do you control how the Couchbase Java client serializes Dates?

Here's my code (Couchbase Java SDK 3)
Cluster cluster = Cluster.connect("localhost", "Administrator", "password");
Collection c = cluster.bucket("default").defaultCollection();
c.upsert("myDocumentId", new Date());
When I look at the resulting document in Couchbase, I see the java.util.Date has been converted to epoch milliseconds:
1602791214674
What I want instead is for the date to be formatted like yyyy-mm-dd.
How can I make that happen?
By default, the Couchbase Java client uses Jackson to serialize and deserialize JSON. Unless you tell it otherwise, it will use an ObjectMapper with default settings. By default, Jackson serializes java.util.Date objects by converting them to milliseconds since the epoch.
You have a couple of choices. If you're using a POJO to represent your document content, you can apply Jackson annotations to the date fields to control how they are [de]serialized. Here's an article that shows how to use the #JsonFormat annotation to control how a date field is serialized.
Alternatively, you can configure an ObjectMapper to change the default way dates are serialized. Here's how you tell the Couchbase Java SDK to use your custom ObjectMapper:
ObjectMapper objectMapper = new ObjectMapper();
objectMapper.disable(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS);
ClusterEnvironment env = ClusterEnvironment.builder()
.jsonSerializer(JacksonJsonSerializer.create(objectMapper))
.build();
Cluster cluster = Cluster.connect("localhost",
ClusterOptions.clusterOptions("Administrator", "password")
.environment(env));
Collection c = cluster.bucket("default").defaultCollection();
c.upsert("myDocumentId", new Date());
cluster.disconnect();
// since we created a custom environment, we're responsible for shutting it down
env.shutdown();
This will give you a document that looks like:
"2020-10-15T19:59:45.685+0000"
If you want a different format, you can configure Jackson to serialize dates however you want.

How to include time zone in Web API 2 JSON dates?

How do I configure the JSON dates produced by my Web API 2 Controller to include the time zone?
Data type used for dates in SQL Server are datetime and I don’t have the option of changing the Legacy database.
Breeze uses Json.NET to serialize/deserialize json. You can configure the serializer settings that Breeze uses by creating a custom class that inherits from Breeze.ContextProvider.BreezeConfig. Breeze will automatically discover this class and create an instance of it for all configuration tasks.
Something like this:
public class CustomBreezeConfig : Breeze.ContextProvider.BreezeConfig
{
protected override Newtonsoft.Json.JsonSerializerSettings CreateJsonSerializerSettings()
{
var ret = base.CreateJsonSerializerSettings();
ret.DateTimeZoneHandling = Newtonsoft.Json.DateTimeZoneHandling.Utc;
// ret.DateTimeZoneHandling = Newtonsoft.Json.DateTimeZoneHandling.Local;
return ret;
}
}
But before you go down this path please read this (the response specifically):
breezejs: date is not set to the right time
Try returning your DateTime formatted with .ToString() and use a custom date and time format like "K". See: http://msdn.microsoft.com/en-us/library/8kb3ddd4(v=vs.110).aspx#KSpecifier for more information.

Appropriate JSON date format when sending from JSP to jQuery

As JSON format doesn't standardize dates subformat, this task is completely on a programmer, right?
When sending dates from PHP to Javascript and back I sent dates as a single integer in UNIX timestamp format (number of seconds since 01/01/1970).
On server:
$now = new DateTime('now');
$now->getTimestamp();
On client:
.success : function (data)
{
var date = new Date(data * 1000);
}
What's the best format for sending dates from JSP? (I'm JSP and Java newbie).
Obviously, it has to be easy encoding/decoding using Java native classes as well as Javascript Date object.
There should not be any problems with overflowing (I'm afraid after 2038 my PHP code will break).
Regards,
new Date(milliseconds) //milliseconds since 1970/01/01 - so you've solved your own problem. I personally prefer to use yyyy-mm-dd hh:ii:ss format as it readable and different from UK and US formats.