To return a JSON response with Spring 3.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?
Spring Framework and Spring Boot provide builtin support for Jackson based XML serialization/deserialization. As soon as you include the jackson-dataformat-xml dependency to your project, it is automatically used instead of JAXB2.
Spring Boot and Jackson The above dependency declaration will work for other Java projects, but in a Spring Boot application, you may encounter errors such as this. The Spring Boot parent POM includes Jackson dependencies. When you include the version number, it overrides the Spring Boot curated dependency versions.
Jackson is one such Java Json library used for parsing and generating Json files. It has built in Object Mapper class which parses json files and deserializes it to custom java objects. It helps in generating json from java objects.
Jackson is a high-performance JSON processor used for Java. It is the most popular library used for serializing Java objects or Map to JSON and vice-versa. It is completely based on Java. Jackson tutorial provides all the basic and advanced concepts of the Jackson library.
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 );
}
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With