Deserialize single string/date from JsonObject to string in java - java

I have a serialized json-date. I wonder if I can just deserialize that single string with the json-date like in c#. But how do you do that in java?
Here is the c# code:
DateTime dateTime = JsonConvert.DeserializeObject<DateTime>(string);
Hope someone can help and that I do not need to create a whole class to do this.
Edit:
Here is the string: "/Date(1630050818893+0300)/"

Since you are trying to deserialize the old .NET text date format, you will have to setup a GSON JsonDeserializer for the Date type.
You can implement one matching and extracting the timestamp value out of the String date as follows:
import com.google.gson.JsonDeserializationContext;
import com.google.gson.JsonDeserializer;
import com.google.gson.JsonElement;
import com.google.gson.JsonParseException;
import java.lang.reflect.Type;
import java.util.Date;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
public class DateDeserializer implements JsonDeserializer<Date> {
private static final Pattern DATE_PATTERN = Pattern.compile("/Date\\((-?\\d+).*\\)/");
#Override
public Date deserialize(JsonElement jsonElement, Type type, JsonDeserializationContext jsonDeserializationContext)
throws JsonParseException {
final Matcher matcher = DATE_PATTERN.matcher(jsonElement.getAsString());
if (matcher.matches()) {
final String timestamp = matcher.group(1);
return new Date(Long.parseLong(timestamp));
} else {
throw new IllegalArgumentException(jsonElement.getAsString() + " does not match /Date(timestamp)/ pattern");
}
}
}
You can then register the custom DateDeserializer as your java.util.Date type deserializer (given that you are using this type in your POJO type):
Gson gson = new GsonBuilder()
.registerTypeAdapter(Date.class, new DateDeserializer())
.create();
ObjectWithDate objectWithDate = gson.fromJson(json, ObjectWithDate.class);
Where ObjectWithDate is a template object holding a java.util.Date field:
public class ObjectWithDate {
private final Date date;
public ObjectWithDate(Date date) {
this.date = date;
}
public Date getDate() {
return date;
}
#Override
public String toString() {
return "ObjectWithDate{" +
"date=" + date +
'}';
}
}

Related

How to serialize Long epoch date format into date using JSONObject

I have json string payload having date in epoch (long) format.But I have to convert that into yyyyMMddHHmmss format.I'm using custom serializers where I can apply that on particular field.But the serialization is not able to apply on that field.
Test.java
private static String json = "{
"dcCountryCode": "US",
"orderDate": 1517855400000
}";
#JsonSerialize(using = CustomLongSerializer.class)
private static Long date;
public static void main(String[] args) {
JSONObject obj = new JSONObject(json);
String country = obj.getString("dcCountryCode");
date = obj.getLong("orderDate");
System.out.println(country);
System.out.println(date);
}
CustomLongSerializer.java
package com.company;
import com.fasterxml.jackson.core.JsonGenerator;
import com.fasterxml.jackson.databind.SerializerProvider;
import com.fasterxml.jackson.databind.ser.std.StdSerializer;
import java.io.IOException;
import java.text.SimpleDateFormat;
// This is for Custom Date serializer
public class CustomLongSerializer extends StdSerializer<Long> {
protected CustomLongSerializer(Class<Long> t) {
super(t);
}
protected CustomLongSerializer() {
this(Long.class);
}
private static final long serialVersionUID = 1L;
#Override
public void serialize(Long value, JsonGenerator gen, SerializerProvider provider) throws IOException {
SimpleDateFormat df = new SimpleDateFormat("yyyyMMddHHmmss");
gen.writeString(df.format(value));
}
}
Expected Out put in yyyyMMddHHmmss format.
But still returning epoch date format.
Can anyone help me with this.
It may be implemented in a simpler way by disabling SerializationFeature.WRITE_DATES_AS_TIMESTAMPS and setting DateFormatter in the mapper:
public class TestDate {
private String dcCountryCode;
private Date date;
// getters/setters
}
// test class
String json = "{\n" +
" \"dcCountryCode\": \"US\",\n" +
" \"date\": 1517855400000\n" +
" }";
ObjectMapper mapper = new ObjectMapper()
.disable(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS)
.setDateFormat(new SimpleDateFormat("yyyyMMddHHmmss"));
TestDate test = mapper.readValue(json, TestDate.class);
System.out.println(mapper.writerWithDefaultPrettyPrinter().writeValueAsString(test));
Output:
{
"dcCountryCode" : "US",
"date" : "20180205203000"
}

How to deserialize diffrents formats of date: YYYY-MM-DD and YYYY-MM

I have list of json objects,one of the fields is date. The problem is that the dates are written in diffrent ways in json.
most of them looks like:
"publishedDate": "2005-01-28"
"publishedDate": "2011-08-29"
"publishedDate": "2016-04-19"
But some of them is like:
"publishedDate": "1998-11"
"publishedDate": "2001-01"
My java object field to which i want to parse
private Date publishedDate;
I got this error:
Cannot deserialize value of type `java.util.Date` from String "2001-01": not a valid representation (error: Failed to parse Date value '2001-01': Cannot parse date "2001-01": while it seems to fit format 'yyyy-MM-dd', parsing fails (leniency? null))
You need to write custom deserialiser for a Date and in both cases properly convert to expected date. Below you can find simple example how to do that:
import com.fasterxml.jackson.core.JsonParser;
import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.DeserializationContext;
import com.fasterxml.jackson.databind.JsonDeserializer;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.annotation.JsonDeserialize;
import java.io.File;
import java.io.IOException;
import java.time.LocalDate;
import java.time.YearMonth;
import java.time.ZoneId;
import java.time.format.DateTimeFormatter;
import java.util.Date;
import java.util.List;
public class JsonApp {
public static void main(String[] args) throws Exception {
File jsonFile = new File("./resource/test.json").getAbsoluteFile();
ObjectMapper mapper = new ObjectMapper();
TypeReference<List<Item>> typeReference = new TypeReference<List<Item>>() {
};
List<Item> readValue = mapper.readValue(jsonFile, typeReference);
System.out.println(readValue);
}
}
class DifferentFormatsDateJsonDeserializer extends JsonDeserializer<Date> {
private DateTimeFormatter localDateFormatter = DateTimeFormatter.ofPattern("yyyy-MM-dd");
private DateTimeFormatter yearMonthFormatter = DateTimeFormatter.ofPattern("yyyy-MM");
#Override
public Date deserialize(JsonParser p, DeserializationContext ctxt) throws IOException {
String value = p.getValueAsString();
try {
if (value.length() == 7) {
YearMonth yearMonth = YearMonth.parse(value, yearMonthFormatter);
return convertToDateViaInstant(yearMonth.atDay(1));
} else {
LocalDate localDate = LocalDate.parse(value, localDateFormatter);
return convertToDateViaInstant(localDate);
}
} catch (Exception e) {
System.out.println(e);
}
return null;
}
public Date convertToDateViaInstant(LocalDate dateToConvert) {
return Date.from(dateToConvert.atStartOfDay()
.atZone(ZoneId.systemDefault())
.toInstant());
}
}
class Item {
#JsonDeserialize(using = DifferentFormatsDateJsonDeserializer.class)
private Date publishedDate;
public Date getPublishedDate() {
return publishedDate;
}
public void setPublishedDate(Date publishedDate) {
this.publishedDate = publishedDate;
}
#Override
public String toString() {
return "Item{" +
"publishedDate=" + publishedDate +
'}';
}
}
Above program for JSON payload:
[
{
"publishedDate": "2005-01-28"
},
{
"publishedDate": "1998-11"
}
]
Prints:
[Item{publishedDate=Fri Jan 28 00:00:00 CET 2005}, Item{publishedDate=Sun Nov 01 00:00:00 CET 1998}]

How do I create a json-string from object? – It returns an empty "[]"?

I'm trying to create make a method, that returns a json-string filled with sample-data. I have created a data-constructor class but when I when I create a data-object and afterwards print it, it for some reason returns an empty json: "[]"?
What am I missing here? Why doesn't it return the data-object I just created?
Here is my main class:
public class SimulatedDevice {
public static void printObject(Object object) {
Gson gson = new GsonBuilder().setPrettyPrinting().create();
System.out.println(gson.toJson(object));
}
public static class TelemetryDataPoint {
public String CreateTelemetryDataPoint() {
ArrayList<Data.TrendData> trendData = new ArrayList<>();
trendData.add(new Data.TrendData("Building1", "2018-08-28T01:03:02.997301Z", 2, "occupants", "int"));
Data data = new Data("B1", "0", "0", trendData);
printObject(data);
String json = new Gson().toJson(data);
return json;
}
}
}
This is my data constructor:
package com.microsoft.docs.iothub.samples;
import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import java.sql.Time;
import java.util.ArrayList;
import java.util.List;
public class Data extends ArrayList {
String Building;
String Floor;
String Zone;
ArrayList<TrendData> Trend;
public Data(String Building, String Floor, String Zone, ArrayList<TrendData> Trend) {
this.Building = Building;
this.Floor = Floor;
this.Zone = Zone;
this.Trend = Trend;
}
public static class TrendData {
String PointId;
String Timestamp;
int Value;
String Type;
String Unit;
public TrendData(String PointId, String Timestamp, int Value, String Type, String Unit) {
this.PointId = PointId;
this.Timestamp = Timestamp;
this.Value = Value;
this.Type = Type;
this.Unit = Unit;
}
}
If you remove 'extends ArrayList' from Data declaration it will work fine. I have not debugged it enough to figure out why Gson does not like the base class being ArrayList.
Here is a possible explanation: Trouble with Gson serializing an ArrayList of POJO's

JSON to Java: How to model lists of objects into generic object class whose object name from json is variable

Suppose I have the following JSON that I'm unable to alter as it's provided over a web feed by someone else. I want to parse this using Jackson to Java objects.
{
"2002": [
{
"d": "description",
"t": "title"
}
],
"2003": [
{
"d": "description",
"t": "title"
}
]
}
The data represents, say, a list of TV programmes with ids=2002, 2003 ...etc, and each programme has a description and title. I want to parse this data into a List of generic Programme classes, where each programme class has fields d and t. I don't want to have separate classes for 2002, 2003 etc objects. Bearing in mind, the 2002, 2003 etc ids are not known until runtime and can evolve over time, and could also be quite a long list of possible values.
Is it possible to model this as a list of generic programmes whose id field is equal to the name of the object name from the json string? In other words, I don't want this:
public class AllProgrammes {
private List<com.example._2002> _2002;
private List<com.example._2003> _2003;
// getters and setters
}
but instead this should just contain List<Programmes>, and each programme object should have an id = 2002, or 2003, or whatever id it is.
Thanks.
If you can use Google Gson, you can do that this way:
Program.class
public class Program {
private String id;
private String title;
private String description;
public Program(String id, String title, String description) {
this.id = id;
this.title = title;
this.description = description;
}
#Override
public String toString() {
return String.format("Program[id=%s, title=%s, description=%s]", this.id, this.title, this.description);
}
}
ProgramsDeserializer.class
import com.google.gson.JsonArray;
import com.google.gson.JsonDeserializationContext;
import com.google.gson.JsonDeserializer;
import com.google.gson.JsonElement;
import com.google.gson.JsonObject;
import com.google.gson.JsonParseException;
import java.lang.reflect.Type;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
class ProgramsDeserializer implements JsonDeserializer<List<Program>> {
#Override
public List<Program> deserialize(JsonElement e, Type type, JsonDeserializationContext jdc) throws JsonParseException {
List<Program> programs = new ArrayList<>(10);
JsonObject root = e.getAsJsonObject();
for (Map.Entry<String, JsonElement> entry : root.entrySet()) {
String id = entry.getKey();
String title = "";
String description = "";
JsonElement arrayElement = entry.getValue();
if (arrayElement.isJsonArray()) {
JsonArray array = arrayElement.getAsJsonArray();
JsonElement objectElement = array.get(0);
if (objectElement.isJsonObject()) {
JsonObject object = objectElement.getAsJsonObject();
title = object.get("t").getAsString();
description = object.get("d").getAsString();
}
}
programs.add(new Program(id, title, description));
}
return programs;
}
}
GsonExample.class
import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import com.google.gson.reflect.TypeToken;
import java.lang.reflect.Type;
import java.util.List;
import java.util.logging.Level;
import java.util.logging.Logger;
public class GsonExample {
private static final Logger logger = Logger.getLogger(GsonExample.class.getName());
private static final String JSON =
"{"
+ "\"2002\": ["
+ "{"
+ "\"d\": \"description\","
+ "\"t\": \"title\""
+ "}"
+ "],"
+ "\"2003\": ["
+ "{"
+ "\"d\": \"description\","
+ "\"t\": \"title\""
+ "}"
+ "]"
+ "}";
public static void main(String[] args) {
GsonExample e = new GsonExample();
e.run();
}
private void run() {
GsonBuilder builder = new GsonBuilder();
Type type = new TypeToken<List<Program>>(){}.getType();
builder.registerTypeAdapter(type, new ProgramsDeserializer());
Gson gson = builder.create();
List<Program> programs = gson.fromJson(JSON, type);
logger.log(Level.INFO, "{0}", programs);
}
}

How to get all attributes names(nested or not) in from JSON response

I have following json response. I am not able to iterate through each Map. Please help me
{"status":"OK","result":{"1":{"Id":"3","Conferencce":"test3","Description":"test3","Admin":"919818559890","Moderator":null,"Keywords":"test3","StartDate":"2011-11-19 12:22:33","EndDate":"2011-11-19 14:22:33","Type":"both","MaxAtendee":"0","MinAtendee":"0","RegAtendee":"0","DescVoiceVideo":null,"Rating":null,"Status":"active","ApproveBy":null,"ApprovedOn":"2011-11-15 14:22:33","ApprovedReason":null,"AdminPin":null,"UserPin":null,"PricePerMin":null,"PricePerConf":null,"ReminderStart":null,"AdminJoin":null,"CreatedOn":"2011-11-17 13:31:27","CreatedBy":"1"},"2":{"Id":"2","Conferencce":"test2","Description":"test","Admin":"919818559899","Moderator":null,"Keywords":"test2","StartDate":"2011-11-18 12:22:33","EndDate":"2011-11-18 14:22:33","Type":"both","MaxAtendee":"0","MinAtendee":"0","RegAtendee":"0","DescVoiceVideo":null,"Rating":null,"Status":"active","ApproveBy":null,"ApprovedOn":"2011-11-15 12:22:33","ApprovedReason":null,"AdminPin":null,"UserPin":null,"PricePerMin":null,"PricePerConf":null,"ReminderStart":null,"AdminJoin":null,"CreatedOn":"2011-11-17 13:31:20","CreatedBy":"1"},"3":{"Id":"1","Conferencce":"test","Description":"tes","Admin":"919818559898","Moderator":null,"Keywords":"test","StartDate":"2011-11-17 12:22:33","EndDate":"2011-11-17 14:22:33","Type":"both","MaxAtendee":"0","MinAtendee":"0","RegAtendee":"0","DescVoiceVideo":null,"Rating":null,"Status":"active","ApproveBy":"1","ApprovedOn":"2011-11-15 12:22:33","ApprovedReason":null,"AdminPin":null,"UserPin":null,"PricePerMin":null,"PricePerConf":null,"ReminderStart":null,"AdminJoin":null,"CreatedOn":"2011-11-17 13:31:15","CreatedBy":"1"}}}
I am not able to iterate through each Map
Instead of treating the three components of the result response as maps, if the names of the keys are consistent and unchanging, I'd define a Java object to match the overall data structure along the following lines. Note this example uses Jackson to handle the JSON-to-Java conversion.
import java.io.File;
import java.math.BigInteger;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Map;
import org.codehaus.jackson.annotate.JsonAutoDetect.Visibility;
import org.codehaus.jackson.annotate.JsonMethod;
import org.codehaus.jackson.map.ObjectMapper;
public class JacksonFoo
{
public static void main(String[] args) throws Exception
{
ObjectMapper mapper = new ObjectMapper();
mapper.setVisibility(JsonMethod.ALL, Visibility.ANY);
mapper.setDateFormat(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"));
Response response = mapper.readValue(new File("input.json"), Response.class);
for (Map.Entry<Integer, Result> entry : response.result.entrySet())
{
System.out.printf("Entry %1$d: %2$s\n", entry.getKey(), entry.getValue());
}
}
}
class Response
{
ResponseStatus status;
Map<Integer, Result> result;
}
enum ResponseStatus
{
OK, NOT_OK
}
class Result
{
int Id;
String Conferencce;
String Description;
BigInteger Admin;
String Moderator;
String Keywords;
Date StartDate;
Date EndDate;
String Type;
int MaxAtendee;
int MinAtendee;
int RegAtendee;
String DescVoiceVideo;
String Rating;
Status Status;
String ApproveBy;
Date ApprovedOn;
String ApprovedReason;
String AdminPin;
String UserPin;
String PricePerMin;
String PricePerConf;
String ReminderStart;
String AdminJoin;
Date CreatedOn;
int CreatedBy;
#Override
public String toString()
{
return String.format("Id: %1$d, Conferencce: %2$s, Description: %3$s, Admin: %4$d, StartDate: %5$tY-%5$tm-%5$td %5$tH:%5$tM:%5$tS", Id, Conferencce, Description, Admin, StartDate);
}
}
enum Status
{
active, inactive
}

Categories