Announcement Announcement Module
Collapse
No announcement yet.
@DateTimeFormat and JSON Page Title Module
Move Remove Collapse
X
Conversation Detail Module
Collapse
  • Filter
  • Time
  • Show
Clear All
new posts

  • @DateTimeFormat and JSON

    Hi

    I try to format a json output with the @DateTimeFormat annotation.
    Here my simple test controller:
    Code:
    @Controller
    public class TestController {
    
      @RequestMapping("/doSomething")
      @ResponseBody
      public User doSomething() {
        User aUser = new User();
        aUser.setName("aName");
        Calendar cal = new GregorianCalendar(1980, Calendar.MARCH, 22);
        aUser.setBirthDay(cal.getTime());
        return aUser;
      }
    }
    And the User object
    Code:
    public class User {
      private String name;    
      
      @DateTimeFormat(iso=ISO.DATE)
      private Date birthDay;
    
      public String getName() {return name;  }
      public void setName(String name) {    this.name = name;  }
      public Date getBirthDay() {  return birthDay;  }
      public void setBirthDay(Date birthDay) {    this.birthDay = birthDay;  }
    }
    Unfortunately this does not work. The output shows the date in milliseconds
    {"name":"aName","birthDay":322527600000}
    I also tried to annotate the get method but with the same result.

    So I'm wondering if this use of @DateTimeFormat is supported. Or is there something I am doing wrong.

    It's not really a big problem because I can use the Jackson annotation @JsonSerialize.

    Code:
      @JsonSerialize(using=MyDateSerializer.class)  
      public Date getBirthDay() {
        return birthDay;
      }
    Code:
    public class MyDateSerializer extends JsonSerializer<Date> {
      @Override
      public void serialize(Date value, JsonGenerator jgen, SerializerProvider provider) throws IOException, JsonProcessingException {
        DateFormat formatter = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ssz");
        jgen.writeString(formatter.format(value));
      }
    }
    This way the output is
    {"name":"aName","birthDay":"1980-03-22T00:00:00CET"}




    Regards
    Ralph

  • #2
    Check these two things:

    1) The User object is defined as a Spring bean in your context, either with a <bean class="com.myCompany.myPackage.User"/> entry in the xml or an @Bean annotation;

    2) In your context xml, there is a context:component-scan entry for the package in which the User object is.

    If one or both those requirements are not met, then of course it won't work since the annotation will be simply ignored.

    Also, I noticed you are not using dependency injection to load the User bean in your controller...

    Comment


    • #3
      As an exercise i changed the User object to a spring managed bean. But that does not work either.

      Code:
      @Named
      public class User {
        private String name;      
        @DateTimeFormat(iso=ISO.DATE)
        private Date birthDay;
      Code:
      @Controller
      public class TestController {
        @Inject
        private User user;  
        @RequestMapping("/doSomething")
        @ResponseBody
        public User doSomething() {        
          user.setName("aName");
          Calendar cal = new GregorianCalendar(1980, Calendar.MARCH, 22);
          user.setBirthDay(cal.getTime());    
          return user;
        }}

      Code:
        <context:component-scan base-package="myPackage" />     
        <mvc:annotation-driven />

      It's not really a problem because the @JsonSerialize annotation works just fine and I will go with that solution. I was only wondering if @DateTimeFormat supports this use case and it looks like it does not.


      Thanks for the help
      Ralph

      Comment


      • #4
        That is very strange nonetheless. Have you tried formatting the date in your controller instead of doing it directly on your business object? (that would be more appropriate in any case since formatting is responsibility of the view and not of the model in the mvc pattern)

        Comment


        • #5
          Formatting the date in the controller would work but then I have to change the type of birthDay property from Date to String.

          Comment


          • #6
            Yeah, that's the route I went with for a similar issue I ran into with one of my services (String properties instead of Dates). Another option would be to make it a Calendar object on your User instead of a Date. Then I think it will format correctly.

            Comment


            • #7
              A possible way to workaround this problem

              Although I found it very difficult to integrate the ConversionService and Jackson, I managed to work out this problem. Obviously Jackson mapper is not well designed for extensions at least in OO perspective, so I had to resort to a brutal force approach.

              https://github.com/ryoasai/spring-mvc-exts

              It seems this problem has bean already filed as a bug, so in the next release we will have a formal solution by the Spring people.
              https://jira.springsource.org/browse/SPR-6731

              Comment


              • #8
                I might also suggest letting Tatu, the creator of Jackson, know about your interest of integrating the Spring ConversionService on the jackson-users mailing list. He's generally responsive to users there and I imagine would work with you to see about making it easier to integrate.

                Comment

                Working...
                X