JSONP与Spring 3.0和Jackson

时间:2011-10-05 01:59:51

标签: spring spring-mvc jsonp jackson

使用Spring 3.0返回JSON响应足以在@ResponseBody内添加@RequestMapping注释和@Controller。如果加载了MapppingJacksonJson库并且客户端使用application/json发送了Accept标头,那么它将起作用。

JSONP怎么样?是否可以退货以及如何退货?

5 个答案:

答案 0 :(得分:12)

此博文显示了正确而紧凑的解决方案:Implementing JSONP in Spring MVC 3.0.x

这个适用于Spring 3.1:XML, JSON, JSON-P Web Service Endpoints in Spring 3.1

对于Spring 3.2,这是基于Jackson2的JSONP转换器:

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);
        }
    }
}

要添加它,请将此bean放在您的配置中:

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 );
    }

}

答案 1 :(得分:12)

Spring 4.1以来,您可以通过以下方式轻松完成:

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

答案 2 :(得分:10)

请参阅Jeremy Grelle关于this blog post的回答。这是another tutorial

答案 3 :(得分:2)

我一直在寻找一种更简单的OOB方法来实现JSONP方法(JSONP / CORS应该内置IMO ......不需要任何自定义代码)...从未找到任何...但是在与Spring接触后团队,事实证明JSONP is now supported OOB in 4.0.5 via MappingJacksonJsonView和内置的supportCORS稍后会跟进。

答案 4 :(得分:1)

查看https://github.com/bhagyas/spring-jsonp-support

我希望它有所帮助。