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"
}
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}]
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
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);
}
}
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
}