JSONP with Spring 3.0 and Jackson

后端 未结 3 981
栀梦
栀梦 2020-12-13 10:53

To return a JSON response with Spring 3.0 is enough to add a @ResponseBody annotation along with the @RequestMapping inside a @Controller

相关标签:
3条回答
  • 2020-12-13 11:28

    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;
        }
    }
    
    0 讨论(0)
  • 2020-12-13 11:50

    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 );
        }
    
    }
    
    0 讨论(0)
  • 2020-12-13 11:51

    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 讨论(0)
提交回复
热议问题