I've read a lot of questions on stackoverflow but i've not got solution to my problem.
This is my Restful service:
@GET
@Path("/GetAllProducts")
@Produces(MediaType.APPLICATION_JSON)
public String getAllProducts() {
return "{\"name\":\"MAC\", \"quantity\":\"10\"}";
}
It works fine on browser but when i used AJAX, it didn't display errors but showed a popup: Failed object[Object]
And my AJAX code:
$.ajax({
url: "http://localhost:8080/Restful/REST/WebService/GetAllProducts",
type: 'GET',
contentType: "application/json; charset=utf-8",
dataType: "jsonp",
success: function() {
alert("Success");
},
error: function(e) {
alert('Failed! ' + e);
}
});
I tried to add: "crossDomain: true" but it didn't work.
Please help me! Thanks!
First let me explain some ways we could debug this..
Change the error
function in the AJAX call. The first argument is actually the jqHXR
object, not the error message. The arguments actually go jqhxr, status, errorMsg
. So if we used the function:
error: function(jqxhr, status, errorMsg) {
alert('Failed! ' + errorMsg);
}
we would see this alert:
Doesn't really help in this case if you don't know what it means, but sometimes it's helpful.
Check the server log
In this case the server log doesn't show any errors meaning the request was processed successfully and the response was returned.
You can see the request is being made with a callback
query parameter. Also pay close attention to the Accept
header, which reads application/javascript
Chrome has the same type of tool, and AFAIK, it is built in, and you can find it under Developer Tools.
There error comes from the dataType
setting in your AJAX request. JSONP is not the same a JSON. JSONP is Javascript code sent back from the server that is meant to be processed by the front end. So jQuery is expecting JSONP format, that's why it set's the headers the application/javascript
and that's why the "Syntax Error" message, as JSON format is not the same syntax as JSONP.
So to fix it, you just simply need to set the dataType
as json
dataType: "json",
success: function(data) {
alert("Success: " + JSON.stringify(data));
},
Now you will see a few things:
The Success message of course:
The request is no longer being made with the callback
query parameter, as that is only for the JSONP protocol.
The Accept
headers now use application/json
Just an FYI, contentType
sets the Content-Type
header. That is only useful when we are sending information, say in a POST request.
I'm not sure if you were expecting JSONP outoup, but if you were, one thing you need to know is that JSONP support is not standard in JAX-RS. It dependends on the JAX-RS implementation, how you will need to configure the support.
First here's how your AJAX request should change to: (or something similar)
$.ajax({
url: "http://localhost:8080/Restful/REST/WebService/GetAllProducts",
type: 'GET',
jsonp: 'callback',
dataType: "jsonp",
success: function(data) {
alert("Success: " + JSON.stringify(data));
},
error: function(jqxhr, status, errorMsg) {
alert('Failed! ' + errorMsg);
}
});
With JSONP, the request will look something like url?callback=someFunctionToCall
, where someFunctionToCall
is what the server wraps around the JSON, and is the name of the our Javascript function we want to be invoked. So the return response might look something like:
someFunctionToCall({"name":"MAC", "quantity":"10"})
With jQuery though, we don't need to send the callback
query parameter. Its value will be made at random. When I tested, this was the request and response:
// request
.../GetAllProducts?callback=jQuery20302583482212586644_1418019088133
// response
jQuery20302583482212586644_1418019088133({"name":"MAC", "quantity":"10"})
On return of the response, our success
function will be called, passing in the data, as would a normal response. The above AJAX request will alert the exact same message as above.
Support for Resteasy
With Reasteasy (3.x.x at least), we should first have the Resteasy Jackson provider
<dependency>
<groupId>org.jboss.resteasy</groupId>
<artifactId>resteasy-jackson2-provider</artifactId>
<scope>provided</scope>
</dependency>
All we need to do is add the JSONP interceptor to our deployment
org.jboss.resteasy.plugins.providers.jackson.JacksonJsonpInterceptor
I haven't gotten the exact science down of which media types need to be added for this support, but I tested with
@Produces({"text/javascript","application/javascript", "application/json"})
For Jersey 2.x
Jersey comes with built in support for JSONP, so we don't need any other dependencies, from the default distribution. We just need to add the @JSONP
annotation.
import javax.ws.rs.GET;
import javax.ws.rs.Path;
import javax.ws.rs.Produces;
import org.glassfish.jersey.server.JSONP;
@Path("/WebService")
public class ProductsResource {
@GET
@Path("/GetAllProducts")
@Produces({"application/json", "application/javascript"})
@JSONP(queryParam = "callback")
public String getAllProducts() {
return "{\"name\":\"MAC\", \"quantity\":\"10\"}";
}
}
Using the same jQuery code as above, will give the same result. See more at JSON with Padding Support
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