How to print JSON a date in correct format returned from a REST API? - mysql

I have written a REST API which gets data from a database. I have a column in my table which stores a date. I am using timestamp format to store the date.
My issue is when I am fetching the data, I'm not able to display the date in the proper format. I am getting 1420655400000 instead of 2015-01-08 00:00:00.
Here is my controller:
#RequestMapping(value="/getEstimation" , method=RequestMethod.GET)
public List<Estimation1> getEstimation(ModelAndView model) throws IOException{
List<Estimation1> estdetail;
estdetail= estimation.getEstimationbyId(5);
return estdetail;
}
Implementation of getEstimationId(double):
#Override
public List<Estimation1> getEstimationbyId(double id) {
// TODO Auto-generated method stub
JdbcTemplate jdbcTemplate = new JdbcTemplate(dataSource);
String sql = "SELECT * FROM estimation where est_id=" +id;
List<Estimation1> estimdetails= jdbcTemplate.query(sql, new RowMapper<Estimation1>()
{
#Override
public Estimation1 mapRow(ResultSet rs, int rowNum) throws SQLException
{
Estimation1 aContact = new Estimation1();
aContact.setDate(rs.getTimestamp("est_date"));
aContact.setEst_contactperson(rs.getString("est_contact_person"));
aContact.setEst_customer(rs.getString("est_customer"));
aContact.setEst_revision(rs.getInt("est_revision"));
aContact.setEst_prjt(rs.getString("est_project"));
aContact.setEst_status(rs.getString("est_status"));
return aContact;
}
});
return estimdetails;
}
Here is the data which I am getting from the database after execution:
[{"date":1420655400000,"est_prjt":"project1","est_revision":0,"est_customer":null,"est_contactperson":"robert","est_status":null,"est_id":0.0,"ec":null}]**
What changes should I make to print the date in the proper format?

You need to give a hint to the Jackson's object mapper of the format in which you want your dates to be deserialized. Following should work out for you
#JsonFormat(shape= JsonFormat.Shape.STRING, pattern="yyyy-MM-dd HH:mm:ss")
private Timestamp date;

Related

Get JSON as input in apache flink

I am trying to receive and access JSON data from a Kafka Topic in Flink. What works is, producing data, send it to a Kafka Topic und receive it in Flink as String. But I want to access the data in an object-oriented way (e.g. extract a specific atrribute from every message)?
Therefore I have a Kafka Producer which sends data (e.g. every 1s) to a Kafka Topic:
ObjectMapper test = new ObjectMapper();
ObjectNode jNode= test.createObjectNode();
jNode.put("LoPos", longPos)
.put("LaPos", latPos)
.put("Timestamp", timestamp.toString());
ProducerRecord<String, ObjectNode> rec = new ProducerRecord<String, ObjectNode>(topicName, jNode);
producer.send(rec);
so the JSON data looks like this:
{"LoPos":10.5,"LaPos":2.5,"Timestamp":"2022-10-31 12:45:19.353"}
What works is, receiving the data and print it as string:
DataStream<String> input =
env.fromSource(
KafkaSource.<String>builder()
.setBootstrapServers("localhost:9092")
.setBounded(OffsetsInitializer.latest())
.setValueOnlyDeserializer(new SimpleStringSchema())
.setTopics(topicName)
.build(),
WatermarkStrategy.noWatermarks(),
"kafka-source");
Print the data as string:
DataStream<String> parsed = input.map(new MapFunction<String, String>() {
private static final long serialVersionUID = -6867736771747690202L;
#Override
public String map(String value) {
System.out.println(value);
return "test";
How can I receive the data in Flink and access it in an object-oriented way (e.g. extract LoPos from every message)? Which approach would you recommend? I tried it with JSONValueDeserializationSchema, but without success...
Thanks!
Update1:
I updated to Flink 1.16 to use JsonDeserializationSchema.
Then I created a Flink Pojo Event like this:
public class Event {
public double LoPos;
public double LaPos;
public Timestamp timestamp;
public Event() {}
public Event(final double LoPos, final double LaPos, final Timestamp timestamp) {
this.LaPos=LaPos;
this.LoPos=LoPos;
this.timestamp=timestamp;
}
#Override
public String toString() {
return String.valueOf(LaPos);
}
}
To read the JSON data, I implemented the following:
KafkaSource<Event> source = KafkaSource.<Event>builder()
.setBootstrapServers("localhost:9092")
.setBounded(OffsetsInitializer.earliest())
.setValueOnlyDeserializer(new JsonDeserializationSchema<>(Event.class))
.setTopics("testTopic2")
.build();
DataStream<Event> test=env.fromSource(source, WatermarkStrategy.noWatermarks(), "test");
System.out.println(source.toString());
System.out.println(test.toString());
//test.sinkTo(new PrintSink<>());
test.print();
env.execute();
So I would expect, when using source.toString() the value of LaPos is getting returned. But all I get is:
org.apache.flink.connector.kafka.source.KafkaSource#510f3d34
What am I doing wrong?
This topic is covered in one of the recipes in the Immerok Apache Flink Cookbook.
In the examples below, I'm assuming Event is a Flink POJO.
With Flink 1.15 or earlier, you should use a custom deserializer:
KafkaSource<Event> source =
KafkaSource.<Event>builder()
.setBootstrapServers("localhost:9092")
.setTopics(TOPIC)
.setStartingOffsets(OffsetsInitializer.earliest())
.setValueOnlyDeserializer(new EventDeserializationSchema())
.build();
The deserializer can be something like this:
public class EventDeserializationSchema extends AbstractDeserializationSchema<Event> {
private static final long serialVersionUID = 1L;
private transient ObjectMapper objectMapper;
/**
* For performance reasons it's better to create on ObjectMapper in this open method rather than
* creating a new ObjectMapper for every record.
*/
#Override
public void open(InitializationContext context) {
// JavaTimeModule is needed for Java 8 data time (Instant) support
objectMapper = JsonMapper.builder().build().registerModule(new JavaTimeModule());
}
/**
* If our deserialize method needed access to the information in the Kafka headers of a
* KafkaConsumerRecord, we would have implemented a KafkaRecordDeserializationSchema instead of
* extending AbstractDeserializationSchema.
*/
#Override
public Event deserialize(byte[] message) throws IOException {
return objectMapper.readValue(message, Event.class);
}
}
We've made this easier in Flink 1.16, where we've added a proper JsonDeserializationSchema you can use:
KafkaSource<Event> source =
KafkaSource.<Event>builder()
.setBootstrapServers("localhost:9092")
.setTopics(TOPIC)
.setStartingOffsets(OffsetsInitializer.earliest())
.setValueOnlyDeserializer(new JsonDeserializationSchema<>(Event.class))
.build();
Disclaimer: I work for Immerok.

Jersey & Jackson date format issues

I am having some issues getting deserializing JSON date with Jersey & Jackson
I have a class, e.g Item:
public class Item {
#JsonFormat(shape=JsonFormat.Shape.STRING, pattern="yyyy-MM-dd")
private Date itemDate;
// other String values and getters/setters
}
The endpoint is as follows:
#Path("/createItem")
#POST
#Produces({MediaType.APPLICATION_JSON})
#Consumes(MediaType.APPLICATION_JSON)
public Response newItem(Item i) {
System.out.println(i.getItemDate());
}
If I POST the following JSON data
{
"itemDate": "2015-03-01"
}
i.getItemDate() is always returning null. Unless I use the default date format yyyy-MM-dd'T'HH:mm:ss.SSS'Z' I was trying to change the format to yyyy-MM-dd but I am unable to do this. I have tried #JsonDeserialize with a custom class as per examples on this site.
It's also worth noting that when using the custom #JsonDeserializer it would never hit any break-point in the custom class, like it was ignoring the annotations e.g
#JsonDeserialiser(using = MyCustomDateFormat.class)
If I have a break point in CustomJsonDateDeserializer it never gets hit.
public class CustomJsonDateDeserializer extends JsonDeserializer<Date> {
#Override
public Date deserialize(JsonParser jsonParser,
DeserializationContext deserializationContext) throws IOException {
SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd");
String date = jsonParser.getText();
try {
return format.parse(date);
} catch (ParseException e) {
throw new RuntimeException(e);
}
}
}
Do I need to do something else to register the deserialization handler, or should it work with one of the approaches above?

Date formate is wrong while adding events in json

I am trying to display events in calendar for that i set the values to json
while setting the values in json date attribute was set as "Mar 1,2017" but i need to set the date like 2017-03-01 in json value.
Here i give my coding
Controller:
#RequestMapping(value = { "/calender_view_get_json" }, method = RequestMethod.GET,headers = "Accept=*/*", produces = "application/json")
public #ResponseBody String viewCalenderJson(Model model, HttpSession session ,HttpServletRequest request,HttpServletResponse response) throws ParseException {
if(request.getRequestedSessionId()!=null&&!request.isRequestedSessionIdValid()){
return "";
}
else{
User user=(User) session.getAttribute("loggedinuserOb");
List<calendar> events=teacherService.getLessonPlanByTeacherId(user.getId());
Gson gson = new Gson();
String jsonEvents = gson.toJson(events);
return jsonEvents;
}
}
Database access:
public List<calendar> getLessonPlanByTeacherId(int t_id){
List<LessonPlan> lst=new ArrayList<LessonPlan>();
List<calendar> cl_list=new ArrayList<calendar>();
try {
Session session=sessionFactory.openSession();
Query q=session.createSQLQuery("select * from sts_class_lesson_plan where teacher_id=(select id from sts_teachers where app_user_id="+t_id+") and month(created_on)=month(utc_date())");
DateFormat df = new SimpleDateFormat("yyyy-MM-dd");
List<Object[]> rows=q.list();
for (Object[] row : rows) {
calendar cl=new calendar();
cl.setStart((Date)row[1]); //May be problem in this line
cl.setTitle((String)row[8]);
cl_list.add(cl);
}
session.close();
}
catch (Exception e) {
e.printStackTrace();
}
return cl_list;
}
service:
public List<calendar> getLessonPlanByTeacherId(int t_id){
//List<calendar> cal_list=new ArrayList<calendar>();
List<calendar> cl_list=teacherDAO.getLessonPlanByTeacherId(t_id);
return cl_list;
}
In datebase class i was getting the database values and set that in to the Model class calendar
current getting date format : Mar 1,2017
required date format :2017-03-01
can any one help me to get this
On way to achieve what you are looking for would be in your controller method viewCalenderJson to replace your Gson instance construction by the following:
Gson gson = new GsonBuilder().setDateFormat("yyyy-MM-dd").create();

Query for JSON String using JdbcTemplate to neo4j?

I want to use a JdbcTemplate and the Neo4j JDBC driver to query my neo4j database and return a JSON string.
Is there an existing method to do this?
I've googled and I can't find one.
It otherwise looks like a matter of creating a home cooked RowMapper as per here.
The query :
MATCH (s:Site) - [r] - (ss:SiteState) return s,ss;
it return a json but for my use i use an object
public class SiteRowMapper implements RowMapper<Site> {
#Override
public Site mapRow(ResultSet rs, int rowNum) throws SQLException {
Site site = new Site();
SiteState siteState = new SiteState();
Gson json = new Gson();
site = json.fromJson(rs.getString("s"), Site.class);
siteState = json.fromJson(rs.getString("ss"), SiteState.class);
site.setName(siteState.getName());
return site;
}
}

jerse Client using JacksonJsonProvider date deserialization

I have a problem with date deserialization on client side. I have to build a simple desktop java aplication that consumes JSON. My code:
ClientConfig config = new DefaultClientConfig();
config.getClasses().add(JacksonJsonProvider.class);
Client client = Client.create(config);
I've tried to use this solution but it doesn't work for me:
How to deserialize JS date using Jackson?
I need a date in this format: "dd.MM.yyyy.", but I'm always getting this error no matter what:
Can not construct instance of java.util.Date from String value '12.10.1971.': not a valid representation (error: Can not parse date "12.10.1971.": not compatible with any of standard forms ("yyyy-MM-dd'T'HH:mm:ss.SSSZ", "yyyy-MM-dd'T'HH:mm:ss.SSS'Z'", "EEE, dd MMM yyyy HH:mm:ss zzz", "yyyy-MM-dd"))
Thank you for your help.
I'm still thinking your linked answer should work, but here is another way which could help you.
Create a Java object for the model you are retrieving.
Let's say it is an item with 2 fields:
public class Item {
private String name;
private String lastModified;
public Item() {}
public String getName() {
return name;
}
public Item setName(String name) {
this.name = name;
return this;
}
public String getLastModified() {
return lastModified;
}
public Modifiable setLastModified(String lastModified) {
this.lastModified = lastModified;
return this;
}
}
Jackson wouldn't try to parse it, because it would have a look into your code and knows it is a string not a date object.
You could than parse it yourself.
If this is to ugly you could hold the lastModified as a date internally, because Jackson is looking for "factory" methods which are taking as a parameter a string, if no date one could be found.