Category Archives: JSON

Jackson 2.x: JSON Serialization Difference for Map.Entry between 2.4.x vs 2.5.x

It appears Jackson 2.4.5 and 2.5.1 behave a little differently when handling Map.Entry.

Let’s assume we have the following bean:-

public class MyBean {
    private Map.Entry<String, String> entry;

    public Map.Entry<String, String> getEntry() {
        return entry;
    }

    public void setEntry(Map.Entry<String, String> entry) {
        this.entry = entry;
    }
}

We have a simple Spring MVC rest controller that creates this bean and returns the JSON data back to the client:-

@RequestMapping(value = "/map", method = RequestMethod.GET)
public ResponseEntity map() {
    final MyBean myBean = new MyBean();
    myBean.setEntry(new AbstractMap.SimpleImmutableEntry<String, String>("a", "1"));

    return new ResponseEntity<MyBean>(myBean, HttpStatus.OK);
}

Jackson 2.4.5 generates the following JSON:-

{
   "entry":
   {
       "key": "a",
       "value": "1"
   }
}

Jackson 2.5.1 generates the following JSON:-

{
   "entry":
   {
       "a": "1"
   }
}

Dang it….

Spring MVC: Handling Joda Data Types as JSON

PROBLEM

Let’s assume we have the following bean that contains Joda’s LocalDate and LocalDateTime objects:-

public class MyBean {
    private LocalDate date;
    private LocalDateTime dateTime;

    public LocalDate getDate() {
        return date;
    }

    public void setDate(LocalDate date) {
        this.date = date;
    }

    public LocalDateTime getDateTime() {
        return dateTime;
    }

    public void setDateTime(LocalDateTime dateTime) {
        this.dateTime = dateTime;
    }
}

This simple Spring MVC rest controller creates this bean and returns the JSON data back to the client:-

@RequestMapping(value = "/joda", method = RequestMethod.GET)
public ResponseEntity joda() {
    MyBean myBean = new MyBean();
    myBean.setDate(LocalDate.now());
    myBean.setDateTime(LocalDateTime.now());
    
    return new ResponseEntity<MyBean>(myBean, HttpStatus.OK);
}

By default, the generated JSON looks like this:-

{
   "date":
   [
       2015,
       3,
       28
   ],
   "dateTime":
   [
       2015,
       3,
       28,
       18,
       12,
       58,
       992
   ]
}

How do we nicely format these values and still retain the correct data types (LocalDate and LocalDateTime) in MyBean instead of writing our custom formatter and store the values as String?

SOLUTION

First, add a dependency for jackson-datatype-joda.

<dependency>
    <groupId>com.fasterxml.jackson.core</groupId>
    <artifactId>jackson-core</artifactId>
    <version>2.5.1</version>
</dependency>
<dependency>
    <groupId>com.fasterxml.jackson.core</groupId>
    <artifactId>jackson-databind</artifactId>
    <version>2.5.1</version>
</dependency>
<dependency>
    <groupId>com.fasterxml.jackson.core</groupId>
    <artifactId>jackson-annotations</artifactId>
    <version>2.5.1</version>
</dependency>
<dependency>
    <groupId>com.fasterxml.jackson.datatype</groupId>
    <artifactId>jackson-datatype-joda</artifactId>
    <version>2.5.1</version>
</dependency>

Next, instruct MappingJackson2HttpMessageConverter to accept a custom ObjectMapper.

<bean id="objectMapper" class="org.springframework.http.converter.json.Jackson2ObjectMapperFactoryBean"
      p:indentOutput="true" p:simpleDateFormat="yyyy-MM-dd'T'HH:mm:ss.SSSZ">
</bean>

<bean class="org.springframework.beans.factory.config.MethodInvokingFactoryBean" p:targetObject-ref="objectMapper"
      p:targetMethod="registerModule">
    <property name="arguments">
        <list>
            <bean class="com.fasterxml.jackson.datatype.joda.JodaModule"/>
        </list>
    </property>
</bean>

<mvc:annotation-driven>
    <mvc:message-converters>
        <bean class="org.springframework.http.converter.StringHttpMessageConverter"/>
        <bean class="org.springframework.http.converter.ResourceHttpMessageConverter"/>
        <bean class="org.springframework.http.converter.json.MappingJackson2HttpMessageConverter">
            <property name="objectMapper" ref="objectMapper"/>
        </bean>
    </mvc:message-converters>
</mvc:annotation-driven>

The generated JSON output now looks like this:-

{
   "date": "2015-03-28",
   "dateTime": "2015-03-28T18:11:16.348"
}

Managing the Order of AJAX Calls on Input Field’s Keyup Event

SCENARIO

Consider the following code:-

$('#employeeSearchField').keyup(function() {
	var query = $(this).val();

	$.get('/employees/api/search', { q: query }, function(data) {
		// do stuff
		...
	});

}).trigger('keyup');

When user types an employee’s name, “Mike”, in the search field, a web service call is fired per character typed. In this example, the following web service calls are made:-

  • GET /employees/api/search?q=M
  • GET /employees/api/search?q=Mi
  • GET /employees/api/search?q=Mik
  • GET /employees/api/search?q=Mike

Let’s assume this web service searches the input string against databases (or flat files, Facebook API, etc) and returns a list of employee JSON objects where their names match the given input string. The code above will take the result and display the employee list on the view.

PROBLEM

Since we can’t control how long each web service call takes to process the request, the order of the returned JSON objects might not match the order of the web service calls. As a result, we may have stale information being presented on the view. Further, we may have the annoying “flicker” problem where the old employee list overrides the new employee list on the view.

SOLUTION

To ensure the order of the returned JSON objects matches the order of the web service calls, we need to keep track each AJAX call’s timestamp. In this example, I’m using Moment.js, a date library, but you can also use the built-in Date object. For now, think of Moment.js as a Swiss Army Knife for date, or a Rambo Knife for date, or a MacGyver Knife for date… okay, maybe not MacGyver Knife since MacGyver can use a tooth pick to solve the date problem.

// keep track latest AJAX call's timestamp
var latestAjaxCallDateTime;

$('#employeeSearchField').keyup(function() {
	var query = $(this).val();

	// before executing the AJAX call, store the latest timestamp
	latestAjaxCallDateTime = moment();
	
	// set the "soon-to-be-executed" AJAX call's timestamp to be the same 
	// as the latest timestamp
	var currentAjaxCallDateTime = latestAjaxCallDateTime;

	$.get('/employees/api/search', { q: query }, function(data) {

		// if current timestamp is older than the latest timestamp, then 
		// omit the request 
		if (currentAjaxCallDateTime.isBefore(latestAjaxCallDateTime)) {
			return;
		}

		// do stuff
		...
	});

}).trigger('keyup');

Yes, this looks pretty hacky, but it works. The whole idea is we will not process the result if it is old. The key of making this whole thing work is to set latestAjaxCallDateTime as a global variable and set currentAjaxCallDateTime as a global variable WITHIN the anonymous function of the input field’s keyup event.

Pretty Print JSON in JavaScript

PROBLEM

You want to display a JSON object in JavaScript.

TAKE 1

console.log(json);

While this works, I find this approach inconvenient when viewing the output in Firebug because I have to click on each generated link to view the details.

TAKE 2

console.log(JSON.stringify(json));

… will generate this:-

[{"title":"Holiday","id":"a1","start":"2014-02-03T09:00:00.000Z","allDay":true},{"title":"Pay Day","id":"a2","start":"2014-03-31T08:00:00.000Z","allDay":true}]

This approach will display the entire JSON object as one long string. This is better than me clicking on each generated link, but this is still fairly unreadable and cumbersome to me if I have a large JSON object.

TAKE 3

console.log(JSON.stringify(json, null, '\t'));

… will generate this:-

[
	{
		"title": "Holiday",
		"id": "a1",
		"start": "2014-02-03T09:00:00.000Z",
		"allDay": true
	},
	{
		"title": "Pay Day",
		"id": "a2",
		"start": "2014-03-31T08:00:00.000Z",
		"allDay": true
	}
]

Aw snap… a nicely formatted JSON string.