S73417H
S73417H

Reputation: 2671

JSON Incorrectly Returns Using Spring MVC 3.2 Deferred Result

I am attempting to use Spring MVC 3.2 asynchronous deferred results for a RESTful JSON service.

Using the synchronous approach:

@ResponseBody
@RequestMapping(value = "/catalog", method = RequestMethod.GET, produces = "application/json")
public Entry catalog() {
  Entry entry = new Entry();
  entry.timestamp = System.currentTimeMillis();
  entry.summary = "Hello World!";
  entry.body = new HashMap<String, Object>();
  entry.body.put("key1", "value1");
  entry.body.put("key2", "value2");
  entry.body.put("key3", "value3");
  return entry;
}

I get the following JSON result:

{"timestamp":1359721240340,"summary":"Hello World!","body":{"key3":"value3","key2":"value2","key1":"value1"}}

Using the asynchronous approach (contrived example):

@ResponseBody
@RequestMapping(value = "/catalogs", method = RequestMethod.GET, produces = "application/json")
public DeferredResult<Entry> catalogs() {
    Entry entry = new Entry();
    entry.timestamp = System.currentTimeMillis();
    entry.summary = "Hello World!";
    entry.body = new HashMap<String, Object>();
    entry.body.put("key1", "value1");
    entry.body.put("key2", "value2");
    entry.body.put("key3", "value3");
    DeferredResult<Entry> result = new DeferredResult<Entry>();
    result.setResult(entry);
    return result;
}

I get the following:

{}{"timestamp":1359721240340,"summary":"Hello World!","body":{"key3":"value3","key2":"value2","key1":"value1"}}

So what's the deal with the prefixed empty object (i.e. {})? Am I doing something obviously stupid or does MappingJackson2JsonView not play nice with the new Async features?

F.Y.I here is my Spring MVC bean configuration:

<bean
    class="org.springframework.web.servlet.view.ContentNegotiatingViewResolver">
    <property name="order" value="1" />
    <property name="contentNegotiationManager">
        <bean class="org.springframework.web.accept.ContentNegotiationManager" />
    </property>
    <property name="defaultViews">
        <list>
            <bean
                class="org.springframework.web.servlet.view.json.MappingJackson2JsonView" />
        </list>
    </property>
</bean>

<bean
    class="org.springframework.web.servlet.view.InternalResourceViewResolver">
    <property name="order" value="2" />
    <property name="prefix" value="/WEB-INF/views/" />
    <property name="suffix" value=".jsp" />
</bean>

Upvotes: 3

Views: 2350

Answers (1)

Java Junky
Java Junky

Reputation: 131

I really wanted to comment rather than "answer" this, but I am as of yet unable to do so. I am getting the same results you are. MappingJackson2JsonView does not seem to work properly with a DeferredResult. Moreover, once I updated to Spring 3.2.3, the resulting JSON was prepended with {} && {} even though I had in my configuration: <property name="prefixJson" value="false" />

My initial attempt to fix this involved writing an HttpServletRequestWrapper and a Filter from which I could scrub the results, but even this doesn't seem to play nicely in Async Servlet land.

The only approach I've found to work for my particular application is filtering out the extra junk using JavaScript. While this works, it does make me want to kill myself or at least pull out a fingernail or two.

I know this isn't very helpful. I hope you find some solace in the fact that I too am weeping over this seemingly simple pain in the balls.

Upvotes: 1

Related Questions