Dropwizard GET the Timestamp using GET returns epoch

240 views
Skip to first unread message

Shammi Syan

unread,
Jul 8, 2015, 6:52:53 AM7/8/15
to dropwiz...@googlegroups.com
Hi,

I have stored the Timestamp in H2 database where is stored in " dd/mm/yyyy hh:mm:ss".

But when i retrieve it using a GET from my DTO with java.sql.Timestamp field ,

the response shows me an EPOCH  value.

Is this the right behvaiour? If yes, how to get a " dd/mm/yyyy hh:mm:ss". as Response ?


Thanks
Syan

Ryan Kennedy

unread,
Jul 10, 2015, 1:54:03 AM7/10/15
to dropwiz...@googlegroups.com
Are you returning the Timestamp from your resource method? i.e.

@GET
public Timestamp getTheTime() {
    …
}

And what MIME type are you sending back? Do you have an @Produces annotation anywhere? All of those things affect how the response is rendered. Without knowing those it's going to be difficult to help you.

If you don't know how JAX-RS generates response bodies from method return values, the Jersey documentation is pretty good at explaining it:


Ryan

--
You received this message because you are subscribed to the Google Groups "dropwizard-user" group.
To unsubscribe from this group and stop receiving emails from it, send an email to dropwizard-us...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Shammi Syan

unread,
Jul 10, 2015, 10:48:34 AM7/10/15
to dropwiz...@googlegroups.com
hi Ryan,

My DTO is like this
========================
@Entity
@Table(name = "Person")
@NamedQueries({
        @NamedQuery(
                name = "com.syan.dto.Person.findPerson",
                query = "SELECT pv FROM Person pv WHERE id = :id"
        )

public class Person
{

@Column(name = "id", nullable = false)
private Long id;

@Column(name = "visitDate", nullable = false)
private Timestamp visitDate;

public Long getId() {
    return id;
}

public void setId(Long id) {
    this.id = id;
}

@JsonProperty
public Timestamp getVisitDate() {
    return visitDate;
}

@JsonProperty
public void setVisitDate(Timestamp visitDate) {
    this.visitDate = visitDate;
}

}

PersonDAO
========================

 public List<Person> findPerson(long id) {
            return list(namedQuery("com.truecaller.rest.dto.findPerson")
               .setParameter("id", id)                 
}

PersonResource
==========================
@Path("/person")
@Produces(MediaType.APPLICATION_JSON)
public class PersonResource {

  private final PersonDAO personDAO;

@GET
@Path("/{Id}")
@Produces(MediaType.APPLICATION_JSON)
@UnitOfWork
public List<Person> listPerson(
@PathParam("idd") LongParam id) {
Long userId = id.get();
return personDAO.findPerson(userId);
}
}

Thanks
Syan

Ryan Kennedy

unread,
Jul 10, 2015, 1:09:29 PM7/10/15
to dropwiz...@googlegroups.com
You're running into Jackson's default date handling, which is to serialize as epoch time. See:


Adding the following to the run() method of your Application subclass will switch to ISO-8601 dates:

    environment.getObjectMapper().configure(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS, false);

If you want something other than that format (I'd recommend ISO-8601 in most cases), the Jackson FAQ linked above has instructions on how to use your own date format.

On an unrelated note, I saw something in your DTO and DAO that I thought I'd point out. You're using a NamedQuery:

    SELECT pv FROM Person pv WHERE id = :id

The simple queries to fetch an object by it's ID can be handled in the DAO without needing the named query:

    public class PersonDAO extends AbstractDAO<Person> {
        public Optional<Person> findById(long id) {
            return Optional.ofNullable(get(id));
        }
    }

You may need to add the @Id annotation to the "id" field on the Person class for this to work, but you should probably be doing that anyway if it's truly the unique ID for the user. I believe that also influences Hibernate caching since it can cache by the primary key.

Your version of PersonDAO is also returning a List<Person>. Is it really possible for multiple Persons to have the same ID in your schema? If so, maybe "id" isn't the proper name for that attribute. If not, you don't need to use list(). Switch to get() and pass it the ID. Then you can get rid of the NamedQuery altogether.

Ryan

Shammi Syan

unread,
Jul 14, 2015, 4:14:51 AM7/14/15
to dropwiz...@googlegroups.com
Thanks Ryan

It is working fine after using 

environment.getObjectMapper().configure(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS, false);

Tatu Saloranta

unread,
Jul 14, 2015, 3:40:46 PM7/14/15
to dropwiz...@googlegroups.com
Something that may be of interest as well is use of @JacksonFeatures annotation, applicable to resource methods.
You can also do:

public class Resource {
   @GET // and other jax-rs stuff
   @JacksonFeatures(serializationDisable={ SerializationFeature.WRITE_DATES_AS_TIMESTAMPS })
   public Stuff getStuff() { ... }

with this, you can enable/disable individual SerializationFeatures and DeserializationFeatures on per-resource basis.

-+ Tatu +-


Reply all
Reply to author
Forward
0 new messages