Using Spring 4.1.6.RELEASE and Jackson libraries v2.5.4
Want to use JSONP in my REST Services using Spring 4; Spring 4 supports JSONP out of the box.
CONFIGURATION
<mvc:annotation-driven
content-negotiation-manager="contentNegotiationManager">
...
</mvc:annotation-driven>
Using contentNegotiationManager in following manner
<bean id="contentNegotiationManager"
class="org.springframework.web.accept.ContentNegotiationManagerFactoryBean">
<property name="defaultContentType" value="application/json" />
<!-- Configuration of Path Extension Based ContentNegotiationStrategy -->
<property name="favorPathExtension" value="false" />
<!-- Configuration of Request Parameter Based ContentNegotiationStrategy -->
<property name="favorParameter" value="true" />
<property name="parameterName" value="formatType" />
<property name="mediaTypes" ref="mediaTypesMapping" />
<!-- Configuration of HTTP ACCEPT Header Based ContentNegotiationStrategy -->
<property name="ignoreAcceptHeader" value="true" />
</bean>
Here is the MediaTypeMapping
<util:map id="mediaTypesMapping">
<entry key="json" value="application/json" />
<entry key="xml" value="application/xml" />
<entry key="jsonp" value="application/javascript" />
</util:map>
Here is the jsonpParameterNames
<util:set id="jsonpParameterNames">
<value>param1</value>
<value>param2</value>
<value>param3</value>
</util:set>
Deployed my REST Service.
hitting the following URL gives data in json format
/contextRoot/info/1?formatType=json
hitting the following URL gives data in xmlformat
/contextRoot/info/1?formatType=xml
hitting the following URL gives 406 EXCEPTION
/contextRoot/info/1?formatType=jsonp¶m1=callback1
Observations
On doing investigation, discovered that MappingJackson2HttpMessageConverter does not supports application/javascript.
Surprised by this since Spring 4 claims to support JSONP Out of the box.
Furthermore, MappingJackson2JsonView does support JSONP out of the box.
Question
Am I missing something in the configuration which once added will enable me to use content type application/javascript out of the box with SPRING 4 for JSONP?
EDIT
Here is my ControllerAdvice Configuration:
<bean id="jsonpAdvice"
class="com.advice.AccountServiceControllerJsonpAdvice">
<constructor-arg ref="jsonpParameterNames" />
</bean>
And here is the ControllerAdvice
public class AccountServiceControllerJsonpAdvice extends
AbstractJsonpResponseBodyAdvice {
private String[] callbackList = {"callback"};
public String[] getCallbackList() {
return callbackList;
}
public void setCallbackList(String[] callbackList) {
this.callbackList = callbackList;
}
public AccountServiceControllerJsonpAdvice(String... callbackList) {
super(callbackList);
}
}
However, this does not enable my application to understand a URL like following and returns a 406 error
/contextRoot/info/1?formatType=jsonp¶m1=callback1
It only makes my application understand a request URL like following and return a JSONP response:
/contextRoot/info/1?param1=callback1
Yes, Spring 4.1+ supports JSONP, but it's not a conversion format per se.
MappingJackson2HttpMessageConverter
supports "application/json"
and "*+json"
media types, but does not support "application/javascript"
. If it did, then you'd expect it to parse javascript code, which is not the case.
Here, we're merely wrapping the output to make it "application/javascript"
, but really, it's still JSON.
Your current configuration is disabling content negotiation with HTTP Accept headers (why?). In order to support JSONP you only need this in your MVC configuration:
<mvc:annotation-driven/>
And an additional ControllerAdvice
like this (see reference documentation):
@ControllerAdvice
public class JsonpAdvice extends AbstractJsonpResponseBodyAdvice {
public JsonpAdvice() {
super("callback");
}
}
That's it.
Now you'll get:
GET /contextRoot/info/1
// will return what's best depending on the Accept header sent by the client
GET /contextRoot/info/1.xml
// will return XML
GET /contextRoot/info/1.json
// will return JSON
GET /contextRoot/info/1.json?callback=myFunction
// will return JSONP wrapped in a "myFunction" call
In your case, you should:
- Remove
"application/javascript"
from your media types mappings, or for backwards compatibility associate"jsonp"
with the"application/json"
media type. - Use
GET /contextRoot/info/1?formatType=json¶m1=callback1
See AbstractJsonpResponseBodyAdvice for more details on the implementation.
来源:https://stackoverflow.com/questions/31170199/spring-4-mappingjackson2httpmessageconverter-does-not-support-application-javas