Time string to Calendar - spring

I am using the jquery timepicker plugin and it works fine. I can select a time and submit my form. I am using spring MVC 3.0 and the problem comes in when I attempt to parse a string ,which represents time, as a java carlendar.
I have been reading up on this date/time conversion, http://www.odi.ch/prog/design/datetime.php, and it seems quite complicated. Can someone please offer some form of advice. Here is my code, which is spring specific.
#RequestMapping(value = "scheduleadd", method = RequestMethod.POST)
public String scheduleadd( #Valid Schedule schedule, BindingResult bindingResult,
#RequestParam("startdate") #org.springframework.format.annotation.DateTimeFormat(iso=ISO.DATE) java.util.Calendar startdate,
#RequestParam("enddate") #org.springframework.format.annotation.DateTimeFormat(iso=ISO.DATE) java.util.Calendar enddate,
#RequestParam("starttime") #org.springframework.format.annotation.DateTimeFormat(iso=ISO.NONE) java.util.Calendar starttime,
#RequestParam("endtime") #org.springframework.format.annotation.DateTimeFormat(iso=ISO.NONE) java.util.Calendar endtime,
#RequestParam("moduleInstanceId") Long mId, Model uiModel, HttpServletRequest httpServletRequest) { //my stuff goes here}
As you can see, I am trying to parse a string like "09:30" as java Carlendar. Do I need the date part? How do I specify the date part ?

Use the pattern attribute of #DateTimeFormat to specify that the "time" fields are not fully-formed ISO datetimes, but rather just times; e.g.:
...
#RequestParam("starttime") #DateTimeFormat(pattern="hh:mm") Calendar starttime,
#RequestParam("endtime") #DateTimeFormat(pattern="hh:mm") Calendar endtime,
...
And in your scheduleadd() method, combine the Calendar fields to get a fully-formed datetime:
startdate.set(Calendar.HOUR_OF_DAY, starttime.get(Calendar.HOUR_OF_DAY));
startdate.set(Calendar.MINUTE, starttime.get(Calendar.MINUTE));
...

Related

Converting java.sql.timestamp to millisecond format

I have a private java.sql.Timestamp myDate in some model (POJO) class like below
private String isActive;
private Date dob;
private Timestamp createdDate;
private Timestamp lastMktPrefUpdateAt;
We were using spring boot version to 1.5.10.RELEASE and REST API response for timestamp field was in millisecond format like below -
{
"isActive": "y",
"lastMktPrefUpdateAt": 1632195609787,
"dob": "08/12/1991",
"createdDate": 1632195609788
}
We have recently upgraded the spring boot version to 2.3.0.RELEASE and this started sending timestamp field in response to some ISO format like below -
{
"isActive": "y",
"lastMktPrefUpdateAt": "2021-09-20T22:10:09.787+0000",
"dob": "07/12/1991",
"createdDate": "2021-09-20T22:10:09.788+0000"
}
Can someone please help answering, how can we format Timestamp back to millisecond format?
We need to format Timestamp at global level meaning without changing all the POJO classes.
Try this in your properties file
spring.jackson.serialization.write-dates-as-timestamps:true
OR
Use #JsonFormat(shape = JsonFormat.Shape.NUMBER) above the property that you want.
Update
If you want to add millis to your timestamp, try to pass the long value to the Timestamp constructor and call the getTime() method to receive a 13-digits timestamp.
long now = System.currentTimeMillis();
Timestamp timeStamp= new Timestamp(now);
System.out.println(timeStamp.getTime());
You could convert that string to a ZonedDateTime object which has a .toInstant().toEpochMilli() method.
Something like:
long millis = ZonedDateTime.of(LocalDateTime.parse(str), ZoneId.of("Etc/UTC")).toInstant().toEpochMilli();
see:
How to get milliseconds from LocalDateTime in Java 8
https://docs.oracle.com/javase/8/docs/api/java/time/LocalDateTime.html
https://docs.oracle.com/javase/8/docs/api/java/time/ZonedDateTime.html
However, I would recommend refactoring the system to use the immutable LocalDatTime object at a later point.
(There may be an appropriate annotation you can put on that timestamp field to parse it in a specific way, but not one that I am aware of.)

Spring Multiple RequestParams vs RequestBody, which is Preferred?

I am new to Spring Rest. While Doing POST, we have 2 options either #RequestBody or #RequestParams.
My query is not what they are. I am pretty well know what they are.
Normally we use #RequestParams for form-urlencoded and #RequestBody for JSON/XML.
I have a scenario as below:
class EmployeeDTO {
long id;
String name;
String age;
String address;
String salary;
//Getters and Setters
}
For POST, I can directly use as void doSomething(#RequestBody EmployeeDTO){ }
and also I can do same thing but using 5 RequestParams
void doSomething(#RequestParam(id) long id, #RequestParam(name) String name, #RequestParam(age) String age, #RequestParam(address) String address, #RequestParam(salary) String salary){ }
I have seen some good sites like Stripe, they following only #RequestParam in their REST Api.
I actually got to understand that we use RequestBody for Complex Input and#RequestParam for simple parameters.
So, my actual query is: In above class, had only 5 parameters, I am thinking its okay going with #RequestParam, But what if there are like 7 or 10 input params, then should I chose RequestBody or (7 or 10) REquestParam?
EDIT:
class Orders {
String id;
Employee employee;
}
It is not really a choice based on "number of data I have to push on server".
Historically and in general the use of the query string is, as the name implies, to query data. And so request param would be the preferred choice when you want to "pull" data HTTP GET
Here if the goal is to "push" data on the server (for instance "to create an employee") you should prefer sending this data in request body.
Moreover the query string is part of the URL, and it can be read by everyone sitting between the clients and the API, so we shouldn’t put sensitive data like passwords into the query string.
you can mimic the format of query string in your body by using the mime type application/x-www-form-urlencoded. Here request body uses the same format as the query string.
parameter=value&parameter2=another

How to store Joda DateTime in MySQL

I've recently started using Joda time library for my test project.
Particularly i have been enjoying the capabilities of DateTime and functions for its manipulation.
My query is how do you store DateTime in MySql. I am using Spring & Hibernate for my application.
my current entity throws deserialisation errors whenever I try and use it:
#Entity
#Table(name = "test_storage")
public class TestEntity {
#Id #GeneratedValue
private int id;
#Column
private DateTime testDate;
//getters and setters
}
The mysql table structure is as follows:
Name: test_storage
Columns:
id INT NOT_NULL, AUTO_INCREMENT
testDate DATETIME
Any advice?
If you are using Hibernate 4+, then you can adopt the Jadira user types which allow you to map DateTime (and other JODA date time related class like LocalDate, LocalDateTime etc) to DB fields using different strategies.
Your mapping will look like
public class TestEntity {
//...
#Column
#Type(type="org.jadira.usertype.dateandtime.joda.PersistentDateTime")
private DateTime testDate;
}
Read the documents to know how to properly use these types to fit your requirements.
The biggest pitfall that you may face soon is, as Java's Date does not include timezone information nor does it sticks to UTC (JODA's user types still need to map to Timestamp/Date internally), you may want to make sure the way you store does provide proper information. For example, either store the date time as UTC, or store timezone information as a separate field, etc.
DATETIME would be my choice. See some more details at What difference between the DATE, TIME, DATETIME, and TIMESTAMP Types and http://infopotato.com/blog/index/datetime_vs_timestamp

Ignoring spring mvc JSR-303 validations for selective entity fields

I have spring4 mvc application to save an Address entity, code bit as follows.
My Controller
#RequestMapping(value = "addAddress", method = POST)
public String registerComplaint(#Valid #ModelAttribute final Address address, final BindingResult resultBinder) {
if (resultBinder.hasErrors())
return "addAddress";
addressService.addAddress(address);
return "redirect:myAddress";
}
My Entity
#Entity
#Table(name = "address")
public class Address {
#NotNull
private String street;
#NotNull
private String pin;
#NotNull
private String createdBy;
........
}
My form conatins only street and pin as field, where as createdBy should be set by me after validating the other form values.
Here the problem is spring JSR303 validation support is validating a field ie createdBy which i don't want to validate by spring mvc.
How can i instruct spring mvc not to validate these kind of optional fields while using #Valid annotation.
Is there any way i can skip fields like this using spring mvc ?
Validation is mainly for user input. Since you will be setting createdBy yourself, just do so before saving it (e.g #PrePersist), or have a new Date as a default value. If you need to enforce a constraint for createBy, you can do so at the schema level.
#Column(nullable=false, ...)
private String createdBy = new Date();
You need to read up on Validation Groups. This lets you use different validators depending on the "scenario"
Use Spring's #Validated annotation to use groups
If you don't protect the createdBy field, a user can change it by altering the POST variables. See DataBinder.setDisallowedFields()
Conceptually, how is a pin related to an address?
It sounds like you want to use a Form Backing Object here (a regular non-JPA POJO made just for a form), and copy values to your real entities.

Post a Joda LocalDateTime as a property. Spring MVC

I have to controller that takes a controller that a Notification and returns a json response.
public #ResponseBody ResponseWrapper<Notification> addNotification(
#RequestParam(required = false) String password,
#Valid Notification notification,
BindingResult bindingResult ){.....}
My Notification that is posted includes a LocalDateTime.
notification.time
How can map a String to LocalDateTime when posting. CustomPropertyEditor or is there a better approach.
Also the time is in my wrapper. How can I format it? LocalDateTime in json includes a lot of information I don't need.
You can annotate your field with #DateTimeFormat and provide a pattern. For example
#DateTimeFormat(pattern = "yyyy-MM-dd")
private LocalDateTime time;
If Spring finds jodatime on your class path, it will use an appropriate DateTimeFormatter to parse the String date value from the request and generate a LocalDateTime object.

Resources