Can't make JSONP call - javascript

this problem is really driving me crazy... I have 2 java web application: appA that publish a REST service which returns some object (which contains an image) in json format, and appB that consumes the service and shows the image. In my local machine it works (though I see the CORS error) but now I'm using a web environment (Layershift) and I'm getting an error "NetworkError: 404 Not Found - http://app-demo.j.layershift.co.uk/myservice/get/c80e9306105f4448?callback=myCallback&_=1477167892656"
I've been reading lot of examples of CORS and JSONP but I can't find what's wrong with my code, can anybody give a hint?
Controller in appA:
#RestController
public class MyController {
#RequestMapping(value="/myservice/get/{somevar}")
public #ResponseBody MyObject getMyObject (#PathVariable String somevar, HttpServletRequest request, HttpServletResponse response) {
MyObject obj = new MyObject();
//some logic
return obj;
}
}
ControllerAdvice in appA:
#ControllerAdvice
public class JsonpAdvice extends AbstractJsonpResponseBodyAdvice {
public JsonpAdvice() {
super("myCallback");
}
}
javascript code with jsonp call in appB:
(function($) {
function myCallback(data) {
if (data.status == "OK") {
//shows the image contained
}
}
$.fn.callWithJsonP = function(somevar) {
$.ajax({
url: "myservice/get/" + somevar,
type: 'GET',
dataType: "jsonp",
jsonpCallback: "myCallback"
});
};
})(jQuery);
Any help would be appreciated, regards
PS: also tried adding the directive "Header add Access-Control-Allow-Origin "*"" in Apache, but same result.

Here's how to perform a JsonP ajax call using Jquery.
E.g.:
$.ajax({
url: "http://localhost/ny-app/getJSfunction",
jsonp: "myfunctionName",
dataType: "jsonp",
data: soomedata,
success: function( response ) {
console.log( response ); // server response
}
});
Handle this call on the server side, and return a function encapsulated javascript code that returns some data. The returned javascript will look like this:
function myfunctioname(){
// some code
return 'whatever you want' ;
}
JQuery ajax will automatically execute the returned javascript function.
Hope this helps.

Finally can make the JSONP call, didn't solve my problem, but I'm able to make the call, so I'll post the changes.
First of all, in the main controller I'm not using #ResponseBody, I've changed it like this:
#RestController
public class MyController {
#RequestMapping(value="/myservice/get/{somevar}")
public MappingJacksonValue getMyObject (#RequestParam String callback, #PathVariable String somevar, HttpServletRequest request, HttpServletResponse response) {
MyObject obj = new MyObject();
//some logic
MappingJacksonValue value = new MappingJacksonValue(obj);
value.setJsonpFunction(callback);
return value;
}
}
Notice the return type is MappingJacksonValue (thanks to JSONP with Spring 3.0 and Jackson), and the javascript code is this:
$.fn.callWithJsonP = function(somevar) {
var url = "/myservice/get/" + somevar + "?callback=myCallback";
$.getJSON(url, function(data) {
if (data.value.status == "OK") {
//show the image contained
}
});
}
There was no need to define a function called "myCallback". I've tested in my local machine and it is working.
Thanks everybody for your suggestions.

Related

Why ajax call send null to servlet? [duplicate]

This question already has answers here:
How should I use servlets and Ajax?
(7 answers)
HTTP request parameters are not available by request.getAttribute()
(1 answer)
Closed 3 years ago.
I'm trying to send the username to the servlet through an ajax call to check its availability, but the servlet show a null pointer exception.
I've also tried with the XMLHttpRequest instead of $.ajax.
This is my Javascript file:
$(document).ready(function() {
$("#reg-form").submit(function() {
var res = true;
if (!testUser()) {
res = false;
$("#erruser").css("display", "block");
$("#username").addClass("errclass");
} else {
$("#erruser").css("display", "none");
$("#username").removeClass("errclass");
}
return res;
});
});
function testUser() {
var el = $("#username").val();
var b = false;
$.ajax({
type: "POST",
url: "CheckUserServlet",
data: { user: el },
dataType: "json",
success: function(bool) {
alert(bool);
if (bool == "si") b = true;
},
error: function() {
alert("errore");
}
});
return b;
}
This is my servlet doPost method:
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
String username=request.getAttribute("user").toString();
System.out.println("username servlet= "+username);
response.setContentType("text/plain");
response.setCharacterEncoding("UTF-8");
if (!ud.doRetrieveByUser(username)) {
response.getWriter().write("si");
return;
}
response.getWriter().write("no");
return;
}
Thanks!
CLIENT SIDE
Your test user function will always return false regardless of if the server is operating correctly because $.ajax() is an async function. There are a few ways around this. In your case, without knowing much more about what you are building, I would suggest removing the return value from your test user function, and moving your logic into the success/failure areas in the ajax callback. This way, the ajax call just does it's thing and lets the success function modify your page however you want.
function testUser() {
var el = $("#username").val();
$.ajax({
type: "POST",
url: "CheckUserServlet",
data: { user: el },
dataType: "json",
success: function(bool) {
alert(bool);
// put logic here
if (bool === "si") {
$("#erruser").css("display", "block");
$("#username").addClass("errclass");
} else {
$("#erruser").css("display", "none");
$("#username").removeClass("errclass");
}
},
error: function() {
alert("errore");
}
});
}
I would also suggest setting up the initial state of your page so that while this request is happening the user is shown something that makes sense. Answer the following question: "what do I show my users when the page does not know yet if it is a test user" and then set the initial state of the page accordingly
SERVER SIDE
I've always found interacting with java & JSON data a bit clunky, and your issue seems like something I've grappled with in the past.
Your question is "why is ajax sending null to the server". It may seem like that but what is really happening is that your server doesn't understand how to interpret the data it is getting. Take a look at this question about getting a JSON payload.. You need to tell your server how to parse the data coming from the client. If you were to inspect the data being sent, I would expect it looks something like this {"user":"blablabla"}.
If you have a class definition already, use that. For this I am using something that looks like this:
public class UserRequest {
String user;
}
// get the body as a string. Requires https://commons.apache.org/proper/commons-io/
String body = IOUtils.toString(request.getReader())
// parse the json with gson. Requires https://github.com/google/gson
Gson g = new Gson();
User u = g.fromJson(body, UserRequest.class);
String username = u.user;

posting one value using ajax (frontend)

I have a problem with connection frontend-backend. I would like to send one value (radio1Value) from javascript function (on click) using jquery ajax. This function should look like I have wrote?
If yes how should REST look in Java? Should this number that backend have received be in function Get() as a parameter?
$.ajax({
url: "someurl",
method: "post",
data: radio1Value
success: function (response) {
alert("Success!");
}
});
#GET
#Path("/{ship}")
public int Get(){
//check in matrix if number from radiovalue exists
}
After checking I would like to send response from backend to frontend.
After advices here what I have got:
$("th").click(function(){
event.preventDefault();
var radio1Value;
var ifEnoughShips;
radio1Value = $("input[name='stat']:checked").val();
//sending radiovalue
$.ajax({
url : "localhost:8126/ship",
method : "get",
data : radio1Value
success: function (response) {
alert("Success!");
ifEnoudhShips=response;
)};
)};
-------------------------
//REST
public class RestTest{
#GET
#Path("abc/{ship}") //here I am not sure because I dont wanna use path
public int CheckHowMany(#PathParam("ship") Integer ship){
Checker ch1 = new Checker();
int res=ch1.CheckNumber(ship);
return res; //0 if number doesn't exists 1 if it does
}
}
You can use the #PathParam notation.
#GET
#Path("/{ship}")
public int Get(#PathParam("ship") Integer ship){
//check in matrix if number from radiovalue exists
return 1; // Return your success int
}
After you are done in your function you can return anything you want to the frontend. Also when you are using ajax make sure you are calling your backend via a GET method and appending the parameter in the call url.
$.ajax({
url: "someurl",
type: "get", //send it through get method
data: radio1Value,
success: function(response) {
//Do Something
},
error: function(xhr) {
//Do Something to handle error
}
});
I am assuming that url : "someurl", is just a placeholder and will actually contain the correct value. Make sure that you're sending the request to http://yourdomain.top/ship since ship is the URL that your Java framework listens to (#Path("/{ship}")
You need to set the correct method header.
You're sending method : "post", while your Java endpoint expects #Get. The Java framework will probably not match the POST request with a GET action.
You need to receive a parameter that the Java framework you are using will be able to bind it to. Probably you need to do this:
#GET
#Path("/{ship}")
public int Get(string radio1Value) {
//check in matrix if number from radiovalue exists
}
What you need to fix is:
Use the correct URL
Use the correct method (use GET or POST in both the request and action)
Have the action receive a parameter so the value you send is obtainable
Edit: for the onclick part you need to wrap your ajax request into an event using jQuery (since you're using this library). You do this like this:
<button id="execute_on_click">Send request</button>
and in your javascript:
$("#execute_on_click").click(function(event) {
event.preventDefault();
$.ajax({
url: "localhost:8126/ship",
method: "get",
data: radio1Value
success: function (response) {
alert("Success!");
}
});
});

Is it possible for a Java controller to pass an attribute to a success ajax call?

As the title says, I want to pass a variable from a controller to a success ajax call function but is it possible? For example:
I have a Java class with a controller like this:
#RequestMapping(value = "checkFruit", method = RequestMethod.POST)
#ResponseBody
public ModelAndView checkFruit(HttpServletRequest request, String fruitInput) {
ModelAndView modelAndView = new ModelAndView();
if (fruitInput.equals("apple")) {
modelAndView.addObject("fruitType", 1); //This is what I want to pass to the success ajax call.
} else if (fruitInput.equals("orange") {
modelAndView.addObject("fruitType", 2); //This is what I want to pass to the success ajax call.
}
modelAndView.setViewName("fruitGarden");
return modelAndView;
}
And a jsp view with an ajax call like this:
$("#checkFruitBtn").click(function () {
var fruitInput = $("input[name=fruitInput]").val();
$.ajax({
type: 'POST',
url: 'checkFruit',
data: 'fruitInput=' + fruitInput,
success: function () {
var fruitType= ${fruitType}; //I want to get the attribule of that "fruitType" variable set in the controller. But this is where things went wrong.
if (fruitType == 1) {
alert("This is an apple.");
} else if (fruitType == 2) {
alert("This is an orange.");
}
window.location.href = "/someURL";
}
});
});
In the above example. When I click the button "checkFruitBtn", it will send an ajax call to the controller "checkFruit". And in this controller, I'll set a variable "fruitType" to send it to the success ajax call function. In this success ajax call function, I'll get the value of the "fruitType" variable to check it and show alert message according to its value... But, things aren't going as planned.
My question is, is there a possible way of getting the value of that "fruitType" variable? I've searched for a getting method but I still can't find one that fitted in my case. I'm terribly sorry if this question have been asked before.
Thanks in advance!
With annotation #ResponseBody, Springmvc converts the returned object to a response body by using an HttpMessageConverter.
ModelAndView usually involves command object and view name.
so you can use ModelAndView with a Jsp page , then use el to evaluate command object values. to use #ResponseBody, Springmvc only return strings.
$.ajax({
type: 'POST',
url: password_url,
data: '',
dataType: 'json',
success: function(response){
var g = response;
var x= g.fruitType; //Now you can do the operation based on the output.

not able to return Json from controller on jsonp request cross domain

I am having a requirement to invoke an action returning Json data on another project from my MVC project (assuming cross origin), Using ajax.
Ajax function
var url1 = 'http://localhost:55308/Reports?type=E&code=1200?callback=?";
$.ajax({
url: url1,
dataType: 'jsonp',
contentType : 'application/json; charset=UTF-8',
success: function (response) {
data = JSON.parse(response);
alert('sucess');
},
error: function(xhr,status, error) { alert('error' + error.message); }
});
It is invoking the controller but returning error :
Uncaught SyntaxError: Unexpected token :{"result1":"abc"}
Controller in another project is like below:
[AllowAnonymous]
public ActionResult Reports(int Code, string type,string callback=null){
--- processing data--(which is working fine)
generatedPath = "df";
StringBuilder sb = new StringBuilder();
JavaScriptSerializer js = new JavaScriptSerializer();
sb.Append(callback + "(");
sb.Append(js.Serialize(generatedPath));
sb.Append(");");
return Json(sb, JsonRequestBehavior.AllowGet);
}
Returning Json result. Should I encapsulate Json to JSONP data in ajax request.
Stuck on this for two days and help on google is not helping.
Please appreciate help. Please
TIA
Edited : Added callback to jsonp request.Also dataserialized which gives me ({"df"}). Is this right?

ASP .NET MVC - Ajax POST action fail

I'm trying to do a simple action with some JavaScript code. I've got some items on a scheduler (DevExpress scheduler component). When I'm double clicking on an appointment (an item then), it should raise an JS function which is the case. My function should get the selected appointment id and pass it to Controller Action. Here is my JS code :
function DoubleClick() {
debugger;
var apt = GetSelectedAppointment(scheduler);
var aptid = apt.appointmentId;
$.ajax({
type: "POST",
url: "/Home/GetAppId",
data: { id: aptid },
dataType: 'json',
success: function () {
alert("ok");
},
error: function () {
alert("error");
}
});
}
And here is my C# code :
[HttpPost]
public JsonResult GetAppId(int id)
{
context = new SchedulingDataClassesDataContext();
DBAppointment app = (from a in context.DBAppointment where a.UniqueID == id select a).FirstOrDefault();
return Json(new {rep = app});
}
As you can see in my JS code, I'm not doing anything special in case of success. However, I never reach the success part. Plus, when I'm looking at the Chrome dev tool (F12), I'm getting that red error message.
POST http://localhost:25206/Home/GetAppId 500 (Internal Server Error)
Anything that I'm doing wrong?
Man, you need to force things as follows
return Json(new {rep = app},"text/json",JsonRequestBehavior.AllowGet);
In addition, mind your navigation properties (if any) in order to avoid circular reference
According to your error your problem somewhere in select your data from DB or creating anonymous object when you try to serialize it to Json. I rewrite your select to simplify it and not creating any anonymous objects when return it from Controller like this:
[HttpPost]
public JsonResult GetAppId(int id)
{
context = new SchedulingDataClassesDataContext();
DBAppointment app = context.DBAppointment.FirstOrDefault(x => x.UniqueID == id);
return Json(app);
}
Does it work like this?
Please remove the name of the property in ajax data and edit that property as below.
function DoubleClick() {
debugger;
var apt = GetSelectedAppointment(scheduler);
var aptid = apt.appointmentId;
$.ajax({
type: "POST",
url: "/Home/GetAppId",
data: aptid,
dataType: 'json',
success: function () {
alert("ok");
},
error: function () {
alert("error");
}
});
}
and edit your controller as follows
[HttpPost]
public JsonResult GetAppId([FromBody]int id)
{
//...
}
Please read this blog post which is a good read and allowed me to understand what's going on.
http://encosia.com/using-jquery-to-post-frombody-parameters-to-web-api/
The original question that I asked
Simple post to Web Api
Try changing the last line of the method to:
return Json(new { rep = app }, JsonRequestBehavior.AllowGet);
You need to tell C# to allow the json to be returned to the client.

Categories

Resources