How to serialize/deserialize an ASP.NET JSON date using Jackson? - java

I'm having some difficulty trying to get Jackson to serialize/deserialize JSON date strings sent from an ASP.NET service. The string is in the following format:
/Date(1234567890123)/
A simple example of the type of output I get from the server is like the following:
{
"name" : "Bob Marley",
"birthdate" : "/Date(1234567890123)/"
}
How can I get Jackson to convert the date to a Java date object? Is there a way to do it without having to write a custom serializer/deserializer?

Your best bet is to write a custom deserializer. Or alternatively, to store the string representation of the date in your bean, but provide an alternative getter that converts the string to a date using a DateFormat instance. The first option is cleaner and more efficient.
See question previously asked here on SO.

I think the ASP.NET service is producing a strange value for the date and would change that if I could. If I cannot, then writing a customer deserializer is the way to go.

Related

Convert a java list of data into a JSON array of array

Good morning, everyone. Hope you're well. Actually I'd like to convert a list with data into a JSON table of this form:
[[45.21406,5.74749,445,"2019-11-05T15:29:45Z"],
[45.21401,5.74752,470,"2019-11-05T15:29:46Z"],
[45.21397,5.74763,472,"2019-11-05T15:29:47Z"],
[45.21393,5.74789,471,"2019-11-05T15:29:48Z"],
[45.21389,5.74849,473,"2019-11-05T15:29:49Z"]
]
My code is the next :
activity.longitude=result.getLastLocation().getLongitude();
activity.latitude=result.getLastLocation().getLatitude();
DateFormat formatter = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss");
activity.dateFormated= formatter.format(new Date());
activity.altitude=result.getLastLocation().getAltitude();
activity.data.add(activity.longitude);
activity.data.add(activity.latitude);
activity.data.add(activity.dateFormated);
activity.data.add(activity.altitude);
Thank you very much for your help.
You need to use a JSON library to make this easy and correct. This is a simple one to get started with.
https://github.com/stleary/JSON-java
so this can be done using a host of different libraries but one that could be particularly helpful is Gson. Unfortunately you have not posted your POJO that represented these values so it's difficult to help you further and give an example but this should help.

GSON - How to always include millisecond in json?

I'm building Android application which interacts with REST API built on .NET.
If my table in SQL Server has 2 rows with the following datetime values:
2019-01-01 00:00:00.000
2019-01-01 00:00:00.113
Then the returned json will have the following values:
2019-01-01T00:00:00
2019-01-01T00:00:00.113
So I don't know how to provide the pattern for setDateFormat when creating an instance of Gson.
If I use GsonBuilder().setDateFormat("yyyy-MM-dd'T'HH:mm:ss"), then my gson can generalize on both cases but it loses millisecond part.
If I use GsonBuilder().setDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSS"), then my gson won't lose millisecond part in the second case but it will throw an exception when dealing with the first case.
How can I successfully parse time in two cases but still achieve millisecond? Any provided solution would be appreciated. I don't mind if things I have to is server side or client side.
After a workaround, I found solution myself, thanks to peter.petrov
It is because I configure my API to return data in json format, rather than xml, in my WebApiConfig.cs. So I feel I can't control how it builds its time format. But I finally found it. This is my WebApiConfig.cs file:
var json = config.Formatters.JsonFormatter;
json.SerializerSettings.PreserveReferencesHandling = Newtonsoft.Json.PreserveReferencesHandling.Objects;
json.SerializerSettings.DateFormatString = "yyyy-MM-dd'T'HH:mm:ss.fff";
config.Formatters.Remove(config.Formatters.XmlFormatter);
Now I server always includes millisecond, no matter what.
That's it.

Parsing Serialized Java objects in Python

The string at the bottom of this post is the serialization of a java.util.GregorianCalendar object in Java. I am hoping to parse it in Python.
I figured I could approach this problem with a combination of regexps and key=val splitting, i.e. something along the lines of:
text_inside_brackets = re.search(r"\[(.*)\]", text).group(1)
and
import parse
for x in [parse('{key} = {value}', x) for x in text_inside_brackets.split('=')]:
my_dict[x['key']] = x['value']
My question is: What would be a more principled / robust approach to do this? Are there any Python parsers for serialized Java objects that I could use for this problem? (do such things exist?). What other alternatives do I have?
My hope is to ultimately parse this in JSON or nested Python dictionaries, so that I can manipulate it it any way I want.
Note: I would prefer to avoid a solution relies on Py4J mostly because it requires setting up a server and a client, and I am hoping to do this within a single
Python script.
java.util.GregorianCalendar[time=1413172803113,areFieldsSet=true,areAllFieldsSet=true,lenient=true,zone=sun.util.calendar.ZoneInfo[id="America/New_York",offset=-18000000,dstSavings=3600000,useDaylight=true,transitions=235,lastRule=java.util.SimpleTimeZone[id=America/New_York,offset=-18000000,dstSavings=3600000,useDaylight=true,startYear=0,startMode=3,startMonth=2,startDay=8,startDayOfWeek=1,startTime=7200000,startTimeMode=0,endMode=3,endMonth=10,endDay=1,endDayOfWeek=1,endTime=7200000,endTimeMode=0]],firstDayOfWeek=1,minimalDaysInFirstWeek=1,ERA=1,YEAR=2014,MONTH=9,WEEK_OF_YEAR=42,WEEK_OF_MONTH=3,DAY_OF_MONTH=13,DAY_OF_YEAR=286,DAY_OF_WEEK=2,DAY_OF_WEEK_IN_MONTH=2,AM_PM=0,HOUR=0,HOUR_OF_DAY=0,MINUTE=0,SECOND=3,MILLISECOND=113,ZONE_OFFSET=-18000000,DST_OFFSET=3600000]
The serialized form of a GregorianCalendar object contains quite a lot of redundancy. In fact, there are only two fields that matter, if you want to reconstitute it:
the time
the timezone
There is code for extracting this in How to convert Gregorian string to Gregorian Calendar?
If you want a more principled and robust approach, I echo mbatchkarov's suggestion to use JSON.

Java - Duplicate method for taking in a string in a different format

Currently working on a small Java date class program.
Okay, so I have a two constructors which take in dates as either parameters (e.g. 28, 12, 1995), and the other constructor as parsing a string (e.g. "25-4-2009") to find and validate the values. I wish to create another constructor which parses a string but in a different date format which on the surface seems pretty simple to do but I'm not sure as to what logic I should be following.
I have tried creating a new constructor with a different variable for the date string, so instead of "dateString", "dateString2" for instance, however Java doesn't like duplicate methods of the same type.
Should I be creating a new object type, so Date2 and using that to parse the new formatted date string? Or is there a better way to do this?
Thanks.
N.B I am not using SimpleDateFormat, and sorry for the poor title.
No. Do not create another Date2 class. One approach you can take is pass another argument in your constructor something like format. Based on what kind of String you pass in you can use the format argument to distinguish.
Here is a code snippet you can use.
Define an enum of supported formats.
public enum DateFormat {DD_MM_YYYY, MM_DD_YYYY};
Your constructor can look something like:
public MyDate(String date, DateFormat dateFormat) {
switch (dateFormat) {
case DD_MM_YYYY:
// Do some parsing
break;
case MM_DD_YYYY:
// Do some other passing
break;
default:
// Handle invalid format
break;
}
}
Hope it helps :)
As you know, it is impossible to have two constructors with same arguments type. In order to achieve desired, I'd recommend to create a flag (or maybe even enum) to indicate whether format 1 or format 2 is expected:
public ClassName(String date, boolean isDMY) {
if (isDMY) {
//date is like 25-4-2009, do parsing, saving, etc
} else {
//date is in another intended format, for example dd.mm.yyyy, do parsing...
}
}
Note that this solution might be not the best one, but for the cases when you have only two possible formats, and your input is trusted (you're sure that constructor won't be invoked with strings like "20051110", for example), then it's ok IMO.
You said that you aren't using SimpleDateFormat. It sounds like you should (unless this is an assignment that does not allow you to) and have your constructor call a method that can parse and format like so:
public Date(String date) {
this.date = formatDate(String dateStr)
}
here is a great article on parsing dates.
If you cannot write a parsing function that is able to determine the date format from the string dynamically, then you must pass extra information to the constructor signaling which date format it should be expecting by means of a second parameter.
How about using a 2nd parameter for your String constructors?
MyDate(String date, char formatType)
You can use switch afterwards for parsing the date.

JSON date converted from ASP - Need converting to Java

I have a slight problem with my JSON string which I have converted from ASP.NET.
The JSON string that C# has converted for me looks like this: /Date(1338199919727)\/
I guess it converts it into milliseconds or something, but how do I get a Java-date out of this huge integer?
I need to get the date displayed properly on my Android app (as a string in a specific format (dd-MM-yyyy : HH), that's why I need it to be in Java. Do I have to manually make some form of converter myself, and figure out how to do it? Or is there some sweet, easy way of doing this?
but how do i get a java-date out of this huge integer?
Ah, that part's easy:
Date dt = new Date(1338199919727L);
You are quite right, it's milliseconds-since-The-Epoch (Jan 1st at midnight, 1970). And Java's Date object has a constructor that accepts that very value.
In general, most JSON parsers have the concept of a "reviver" function or class that you can pass to them, which will let you pre-process values as the JSON is being deserialized. I don't know Android's JSON parser well enough to know if it has one. If not (which would be a bit backward), you'd have to walk the resulting object graph looking for properties that had become strings and converting them to dates after-the fact.
I hope this is what you need
long Ldate = 1338199919727L;
Date date = new Date(Ldate * 1000);
String strdate = (String) DateFormat.format("MM/dd/yy h:mmaa", date);

Categories

Resources