I am trying to get my Spring rest controller to return jsonp but I am having no joy
The exact same code works ok if I want to return json but I have a requirement to return jsonp I have added in a converter I found source code for online for performing the jsonp conversion
I am using Spring version 4.1.1.RELEASE and Java 7
Any help is greatly appreciated
Here is the code in question
mvc-dispatcher-servlet.xml
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:mvc="http://www.springframework.org/schema/mvc"
xsi:schemaLocation="
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd
http://www.springframework.org/schema/mvc
http://www.springframework.org/schema/mvc/spring-mvc.xsd">
<bean id="contentNegotiationManager" class="org.springframework.web.accept.ContentNegotiationManagerFactoryBean">
<property name="favorPathExtension" value="false" />
<property name="favorParameter" value="true" />
<property name="parameterName" value="mediaType" />
<property name="ignoreAcceptHeader" value="false"/>
<property name="useJaf" value="false"/>
<property name="defaultContentType" value="application/json" />
<property name="mediaTypes">
<map>
<entry key="atom" value="application/atom+xml" />
<entry key="html" value="text/html" />
<entry key="jsonp" value="application/javascript" />
<entry key="json" value="application/json" />
<entry key="xml" value="application/xml"/>
</map>
</property>
</bean>
<bean class="org.springframework.web.servlet.view.ContentNegotiatingViewResolver">
<property name="contentNegotiationManager" ref="contentNegotiationManager" />
<property name="viewResolvers">
<list>
<bean class="org.springframework.web.servlet.view.BeanNameViewResolver" />
<bean
class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="prefix" value="/WEB-INF/templates/slim/${views.template.directory}/" />
<property name="suffix" value=".jsp" />
</bean>
</list>
</property>
<property name="defaultViews">
<list>
<bean class="com.webapp.handler.MappingJacksonJsonpView" />
</list>
</property>
</bean>
</beans>
com.webapp.handler.MappingJacksonJsonpView
package com.webapp.handler;
import java.util.Map;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.web.servlet.view.json.MappingJackson2JsonView;
public class MappingJacksonJsonpView extends MappingJackson2JsonView {
/** Local log variable. **/
private static final Logger LOG = LoggerFactory.getLogger(MappingJacksonJsonpView.class);
/**
* Default content type. Overridable as bean property.
*/
public static final String DEFAULT_CONTENT_TYPE = "application/javascript";
@Override
public String getContentType() {
return DEFAULT_CONTENT_TYPE;
}
/**
* Prepares the view given the specified model, merging it with static
* attributes and a RequestContext attribute, if necessary.
* Delegates to renderMergedOutputModel for the actual rendering.
* @see #renderMergedOutputModel
*/
@Override
public void render(Map<String, ?> model, HttpServletRequest request, HttpServletResponse response) throws Exception {
LOG.info("Entered render Method :{}", request.getMethod());
if("GET".equals(request.getMethod().toUpperCase())) {
LOG.info("Request Method is a GET call");
Map<String, String[]> params = request.getParameterMap();
if(params.containsKey("callback")) {
String callbackParam = params.get("callback")[0];
LOG.info("callbackParam:{}", callbackParam);
response.getOutputStream().write(new String(callbackParam + "(").getBytes());
super.render(model, request, response);
response.getOutputStream().write(new String(");").getBytes());
response.setContentType(DEFAULT_CONTENT_TYPE);
}
else {
LOG.info("Callback Param not contained in request");
super.render(model, request, response);
}
}
else {
LOG.info("Request Method is NOT a GET call");
super.render(model, request, response);
}
}
}
Controller Method In Question
@RequestMapping(value = { "/sources"}, method = RequestMethod.GET,
produces={MediaType.ALL_VALUE,
"text/javascript",
"application/javascript",
"application/ecmascript",
"application/x-ecmascript",
"application/x-javascript",
MediaType.APPLICATION_JSON_VALUE})
@ResponseBody
public Object getSources(@PathVariable(value = API_KEY) String apiKey,
@RequestParam(value = "searchTerm", required = true) String searchTerm,
@RequestParam(value = "callBack", required = false) String callBack) {
LOG.info("Entered getSources - searchTerm:{}, callBack:{} ", searchTerm, callBack);
List<SearchVO> searchVOList = myServices.findSources(searchTerm);
if (CollectionUtils.isEmpty(searchVOList)) {
LOG.error("No results exist for the searchterm of {}", searchTerm);
return searchVOList;
}
LOG.debug("{} result(s) exist for the searchterm of {}", searchVOList.size(), searchTerm);
LOG.info("Exiting getSources");
return searchVOList;
}
**Jquery Ajax Code **
$.ajax({
type: "GET",
url: "http://localhost:8080/my-web/rest/sources,
data: {
"searchTerm": request.term
},
//contentType: "application/json; charset=utf-8",
//dataType: "json",
contentType: "application/javascript",
dataType: "jsonp",
success: function(data) {
alert("success");
},
error: function(XMLHttpRequest, textStatus, errorThrown) {
alert("Failure");
}
});
A snippet of the error stacktrace that I get is as follows
org.springframework.web.HttpMediaTypeNotAcceptableException: Could not find acceptable representation
at org.springframework.web.servlet.mvc.method.annotation.AbstractMessageConverterMethodProcessor.writeWithMessageConverters(AbstractMessageConverterMethodProcessor.java:168) ~[spring-webmvc-4.1.1.RELEASE.jar:4.1.1.RELEASE]
at org.springframework.web.servlet.mvc.method.annotation.AbstractMessageConverterMethodProcessor.writeWithMessageConverters(AbstractMessageConverterMethodProcessor.java:101) ~[spring-webmvc-4.1.1.RELEASE.jar:4.1.1.RELEASE]
at org.springframework.web.servlet.mvc.method.annotation.RequestResponseBodyMethodProcessor.handleReturnValue(RequestResponseBodyMethodProcessor.java:198) ~[spring-webmvc-4.1.1.RELEASE.jar:4.1.1.RELEASE]
at org.springframework.web.method.support.HandlerMethodReturnValueHandlerComposite.handleReturnValue(HandlerMethodReturnValueHandlerComposite.java:71) ~[spring-web-4.1.1.RELEASE.jar:4.1.1.RELEASE]
at org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:122) ~[spring-webmvc-4.1.1.RELEASE.jar:4.1.1.RELEASE]
at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandleMethod(RequestMappingHandlerAdapter.java:781) ~[spring-webmvc-4.1.1.RELEASE.jar:4.1.1.RELEASE]
at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:721) ~[spring-webmvc-4.1.1.RELEASE.jar:4.1.1.RELEASE]
at org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:83) ~[spring-webmvc-4.1.1.RELEASE.jar:4.1.1.RELEASE]
at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:943) ~[spring-webmvc-4.1.1.RELEASE.jar:4.1.1.RELEASE]
at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:877) ~[spring-webmvc-4.1.1.RELEASE.jar:4.1.1.RELEASE]
at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:966) [spring-webmvc-4.1.1.RELEASE.jar:4.1.1.RELEASE]
at org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:857) [spring-webmvc-4.1.1.RELEASE.jar:4.1.1.RELEASE]
at javax.servlet.http.HttpServlet.service(HttpServlet.java:620) [servlet-api.jar:na]
at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:842) [spring-webmvc-4.1.1.RELEASE.jar:4.1.1.RELEASE]
at javax.servlet.http.HttpServlet.service(HttpServlet.java:727) [servlet-api.jar:na]