开发者

JSONP with Spring 3.0 and Jackson

开发者 https://www.devze.com 2023-04-10 12:40 出处:网络
To return a JSON response with Spring 3开发者_StackOverflow.0 is enough to add a @ResponseBody annotation along with the @RequestMapping inside a @Controller. Provided that MapppingJacksonJson library

To return a JSON response with Spring 3开发者_StackOverflow.0 is enough to add a @ResponseBody annotation along with the @RequestMapping inside a @Controller. Provided that MapppingJacksonJson library is loaded and that the client sends Accept header with application/json, it will work.

What about JSONP? Is it possible to return it and how?


This blog post shows a correct and compact solution: Implementing JSONP in Spring MVC 3.0.x

This one works better for Spring 3.1: XML, JSON, JSON-P Web Service Endpoints in Spring 3.1

For Spring 3.2, here is a Jackson2 based JSONP converter:

import java.io.IOException;
import org.springframework.http.HttpOutputMessage;
import org.springframework.http.converter.HttpMessageNotWritableException;
import org.springframework.http.converter.json.MappingJackson2HttpMessageConverter;
import com.fasterxml.jackson.core.JsonEncoding;
import com.fasterxml.jackson.core.JsonGenerator;
import com.fasterxml.jackson.core.JsonProcessingException;

public class MappingJackson2JsonpHttpMessageConverter
    extends MappingJackson2HttpMessageConverter {

    @Override
    protected void writeInternal(Object object, HttpOutputMessage outputMessage)
        throws IOException, HttpMessageNotWritableException {
        JsonEncoding encoding = getJsonEncoding(outputMessage.getHeaders().getContentType());
        JsonGenerator jsonGenerator = this.getObjectMapper().getFactory().createJsonGenerator(outputMessage.getBody(), encoding);        

        try {
            String jsonPadding = "callback";            

            // If the callback doesn't provide, use the default callback
            if (object instanceof IJsonpObject) {
                String jsonCallback = ((IJsonpObject)object).getJsonCallback();
                if (jsonCallback != null) {
                    jsonPadding = jsonCallback;
                }
            }            

            jsonGenerator.writeRaw(jsonPadding);
            jsonGenerator.writeRaw('(');
            this.getObjectMapper().writeValue(jsonGenerator, object);
            jsonGenerator.writeRaw(");");
            jsonGenerator.flush();
        } catch (JsonProcessingException ex) {
            throw new HttpMessageNotWritableException("Could not write JSON: " + ex.getMessage(), ex);
        }
    }
}

To add it, put this bean in your configuration:

import java.util.List;
import org.springframework.http.MediaType;
import org.springframework.http.converter.HttpMessageConverter;
import org.springframework.web.servlet.config.annotation.ContentNegotiationConfigurer;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter;
import com.google.common.collect.Lists;

public class MyWebMvcConfigurer extends WebMvcConfigurerAdapter {

    @Override
    public void configureMessageConverters( List<HttpMessageConverter<?>> converters ) {
        MappingJackson2JsonpHttpMessageConverter converter = new MappingJackson2JsonpHttpMessageConverter();

        converter.setSupportedMediaTypes( Lists.newArrayList(
            new MediaType( "application", "x-javascript" ),
            new MediaType( "application", "javascript" ),
            new MediaType( "text", "javascript" )
        ) );

        converters.add( converter );
    }

}


Since Spring 4.1 you can easy do it this way:

@RestController
public class MyController {
    @RequestMapping("/endpoint")
    MappingJacksonValue getData(@RequestParam String callback) {
        MappingJacksonValue value = new MappingJacksonValue(new MyPojo());
        value.setJsonpFunction(callback);
        return value;
    }
}


I was looking for a simpler, OOB approach for JSONP approach (JSONP/CORS should be built-in IMO...not require any custom code)...never found any...but after reaching out with the Spring team, it turns out that JSONP is now supported OOB in 4.0.5 via MappingJacksonJsonView and built-in supportCORS to follow later.

0

精彩评论

暂无评论...
验证码 换一张
取 消