Announcement

Collapse
No announcement yet.
X
  • Filter
  • Time
Clear All
new posts

    Can I Customize How JSON is Returned From IDACall?

    I'm using SmartClient 8.2.

    I've got a custom data source that returns a Java object from its executeFetch() method. One of the fields in this object is of type Joda DateTime (but for this question, it could really be any custom Java object). Is there a way to customize how this field is serialized to JSON in the response from the IDACall servlet? Currently DateTime gets serialized to something like:
    Code:
    date:{afterNow:false,beforeNow:true,centuryOfEra:20,chronology:{zone:{ID:"UTC",fixed:true}},dayOfMonth:7,dayOfWeek:6,dayOfYear:189,equalNow:false,era:1,hourOfDay:7,millis:1341644400000,millisOfDay:25200000,millisOfSecond:0,minuteOfDay:420,minuteOfHour:0,monthOfYear:7,secondOfDay:25200,secondOfMinute:0,weekOfWeekyear:27,weekyear:2012,year:2012,yearOfCentury:12,yearOfEra:2012,zone:{ID:"UTC",fixed:true}}
    I'd like to just have the milliseconds returned if possible, something like this:
    Code:
    date:1341644400000
    I can create a Javascript Date object out of this on the client side and then go from there.

    Thanks.

    #2
    See the server-side JSTranslater JavaDoc - specifically the toJS() method discusses several ways of customizing translation.

    Comment


      #3
      Thanks for pointing me in the right direction.

      The Javadoc page from Isomorphic indicates that there are four options for custom serialization:

      1) translate objects to collections of basic types
      2) implement a collections interface
      3) provide a JSONFilter for the object
      4) implement IToJSON

      Because I'm working with a class from a library (Joda DateTime), I'm not able to modify the class to implement an interface. So options 2 and 4 are out.

      What I ended up doing is creating a wrapper class that wraps my object that contains the DateTime field. The wrapper class's getDate() field returns the milliseconds as a long value. Here's the relevant code:

      My original Java object:
      Code:
      public class Foo {
      
        private DateTime date;
      
        public DateTime getDate() {
          return date;
        }
      }
      My wrapper:
      Code:
      public class FooWrapper {
      
        private Foo foo;
      
        public FooWrapper(Foo foo) {
          this.foo = foo;
        }
      
        public long getDate() {
          return foo.getDate().getMillis();
        }
      }
      How I used the wrapper in my custom datasource:
      Code:
      public class FooDataSource extends BasicDataSource {
      
      ...
      
        public DSResponse executeFetch(DSRequest req) {
          List<FooWrapper> wrappedFoos = wrapFoos(service.findAllFoos());
          DSResponse dsResp = new DSResponse(this, wrappedFoos);
          return dsResp;
        }
      
        private List<FooWrapper> wrapFoos(List<Foo> foos) {
          List<WrappedFoos> wrappedFoos = new ArrayList<WrappedFoo>();
          for (Foo foo : foos) {
            wrappedFoos.add(new WrappedFoo(foo));
          }
          return wrappedFoos;
        }
      }
      When the IDACall servlet returns JSON from the fetch call, the date field is now a long (milliseconds since 1/1/1970).

      A suggestion for the hard-working folks at Isomorphic that make this all possible: you could handle JSON serialization similar to the way the Jackson library handles it, using custom serializers that are registered for a type. This keeps the serialization logic separate from the bean, and I think it's clean and elegant. See here: http://wiki.fasterxml.com/JacksonHowToCustomSerializers.

      Comment


        #4
        It would be less code to just take DSResponse.getDataList(), change all the JODA Date instances, and provide the modified data back via dsResponse.setData().

        We didn't implement serializers by type because it's unclear if the cost of all those Java reflection calls would be acceptable on every JVM.

        Comment

        Working...
        X