This situation is killing me. A JSONP Jquery Ajax request from http://example.com:80 to http://example1.com:8080 never sets the Content Type and Spring MVC complains on the server when trying to serialize my javabean in the controller parameter. If I test the JSONP request on either website calling the same domain, it sets the content type. Is this a port issue? I am testing a WordPress site to Spring MVC API on my local.
handlerMapperInvoker.java – This is where the error occurs in the Spring Framework
MediaType contentType = inputMessage.getHeaders().getContentType();
if (contentType == null) {
StringBuilder builder = new StringBuilder(ClassUtils.getShortName(methodParam.getParameterType()));
String paramName = methodParam.getParameterName();
if (paramName != null) {
builder.append(' ');
builder.append(paramName);
}
throw new HttpMediaTypeNotSupportedException(
"Cannot extract parameter (" + builder.toString() + "): no Content-Type found");
}
apicontroller.java – API Side
@RequestMapping(value="/badge/get")
public @ResponseBody IHttpResponse getBadge(@RequestBody GetBadgeRequest request) {
apiService.getBadge(request);
return request.getResponse();
}
api.js – WordPress
getBadge : function(id) {
var model =
{
id : id
};
this.call({ url: 'badge/get.json', type: 'GET', data: model, callback: function(data)
{
alert(data);
}});
},
call : function(options) {
var def = {
url : '',
type : "POST",
dataType : 'jsonp',
data : undefined,
contentType : "application/json",
callback : function() {},
errorCallback : function() {}
};
$.extend(def, options);
var sessionToken = api.getSession();
if(sessionToken && sessionToken != "undefined") {
if(!def.data) {
def.data = {};
}
def.data.sessionToken = sessionToken;
}
var url = config.baseUrl + def.url;
// Abort Request If Another One Is Made
if (config.request != null)
config.request.abort();
if (def.showLoader) {
application.loader(true);
}
config.request = $
.ajax({
url : url,
type : def.type,
data : { request: $.toJSON(def.data) },
dataType : def.dataType,
contentType : def.contentType,
success : function(data) {
if (def.showLoader) {
JSONP requests outside the current domain are always made as script requests to get around the same origin policy. The parameters will be encoded into the url (i.e., no POST, only a GET for a script). Since there’s no way to specify a content type on a script request, it doesn’t appear. When done locally, it keeps the content type since it’s actually making a real AJAX request.
Essentially what an AJAX request for JSONP to a different domain translates to is:
And it expects to receive in return a script like:
Note when using jQuery
somefunction
is actually an automatically generated name.