how to call ajax success and error function from controller? - ajax

I have ajax function
$.ajax({
....
type: "POST",
url: "",
data: "",
success: function(){
},
error: function(XMLHttpRequest, textStatus, errorThrown) {
}
});
& controller code is
public #ResponseBody
GenericResponse abc() {
try {
....
} catch (Exception ex) {
ex.printStackTrace();
return new GenericResponse("Failed", ex.getMessage(), 500);
}
return new GenericResponse("Success", "", 200);
}
where GenericResponse is
public class GenericResponse
{
private String status;
private String error;
private int code;
public GenericResponse(String s, String e, int c)
{
this.status = s;
this.error = e;
this.code = c;
}
....
}
So for success & failure I am sending genericresponse with status but for both it goes inside success callback function.
I understand that it is gennericResponse so ajax would consider it as success only . If exception comes
I want it to go to error callback function. How to do that?

Instead of returning a GenericResponse, try returning a ResponseEntity instead.
You would do:
return new ResponseEntity<GenericResponse>(successGenericResponse, HttpStatus.OK);
or
return new ResponseEntity<GenericResponse>(failGenericResponse, HttpStatus.INTERNAL_SERVER_ERROR);

Related

AJAX + Spring MVC: Cannot find destination

I have a form which should send user input via ajax to my spring mvc controller.
But I always get an Error as you can see below. I implemented into getSearchResultViaAjax a System.out.println("in getSearchResultViaAjax");
but it is never called in the console. Any idea how I could fix that?
Error Message:
{
"readyState": 4,
"responseText": "{\"timestamp\":\"2018-03-24T18:33:14.749+0000\",\"status\":404,\"error\":\"Not Found\",\"message\":\"No message available\",\"path\":\"/$%7Bhome%7D/search/api/getSearchResult\"}",
"responseJSON": {
"timestamp": "2018-03-24T18:33:14.749+0000",
"status": 404,
"error": "Not Found",
"message": "No message available",
"path": "/$%7Bhome%7D/search/api/getSearchResult"
},
"status": 404,
"statusText": "error"
}
I tried in AJAX also paths like:
url: "/search/api/getSearchResult"
url: "search/api/getSearchResult"
and get this then for example
{
"readyState": 4,
"responseText": "{\"timestamp\":\"2018-03-24T19:48:43.638+0000\",\"status\":500,\"error\":\"Internal Server Error\",\"message\":\"Error resolving template \\\"search/api/getSearchResult\\\", template might not exist or might not be accessible by any of the configured Template Resolvers\",\"path\":\"/search/api/getSearchResult\"}",
"responseJSON": {
"timestamp": "2018-03-24T19:48:43.638+0000",
"status": 500,
"error": "Internal Server Error",
"message": "Error resolving template \"search/api/getSearchResult\", template might not exist or might not be accessible by any of the configured Template Resolvers",
"path": "/search/api/getSearchResult"
},
"status": 500,
"statusText": "error"
}
Controller:
#Controller
#RequestMapping("")
public class View {
#Autowired
PController controller;
List<User> users;
/**
* After user coin choice is filled with details, it arrives here.
*
* #param httpEntity the http entity
* #return the string
*/
#RequestMapping(method = RequestMethod.POST)
public String arriveAfterSetup(
HttpEntity<String> httpEntity,
#RequestParam(required = false, value = "name") String name,
#RequestParam(required = false, value = "age") String age,
final ModelMap modelMap
) {
modelMap.put("elementList", controller.getDatabase().getPersonLinkedList());
return "main/mainpage";
}
#RequestMapping(method = RequestMethod.GET)
public String exchangeViewAfterEdit(ModelMap modelMap
) {
modelMap.put("elementList", controller.getDatabase().getPersonLinkedList());
return "main/mainpage";
}
#RequestMapping(value = "/edit/{id}", method = RequestMethod.POST)
public void editPerson(ModelMap modelMap,
#PathVariable String id,
#RequestParam("name") String name,
#RequestParam("age") Double age
) {
//update db
}
// #RequestBody - Convert the json data into object (SearchCriteria) mapped by field name.
// #JsonView(Views.Public.class) - Optional, limited the json data display to client.
#JsonView(Views.Public.class)
#RequestMapping(value = "/search/api/getSearchResult")
public AjaxResponseBody getSearchResultViaAjax(#RequestBody SearchCriteria search) {
System.out.println("in getSearchResultViaAjax");
AjaxResponseBody result = new AjaxResponseBody();
if (isValidSearchCriteria(search)) {
List<User> users = findByUserNameOrEmail(search.getUsername(), search.getEmail());
if (users.size() > 0) {
result.setCode("200");
result.setMsg("");
result.setResult(users);
} else {
result.setCode("204");
result.setMsg("No user!");
}
} else {
result.setCode("400");
result.setMsg("Search criteria is empty!");
}
//AjaxResponseBody will be converted into json format and send back to client.
return result;
}
private boolean isValidSearchCriteria(SearchCriteria search) {
boolean valid = true;
if (search == null) {
valid = false;
}
if ((StringUtils.isEmpty(search.getUsername())) && (StringUtils.isEmpty(search.getEmail()))) {
valid = false;
}
return valid;
}
// Init some users for testing
#PostConstruct
private void iniDataForTesting() {
users = new ArrayList<User>();
User user1 = new User("mkyong", "pass123", "mkyong#yahoo.com", "012-1234567", "address 123");
User user2 = new User("yflow", "pass456", "yflow#yahoo.com", "016-7654321", "address 456");
User user3 = new User("laplap", "pass789", "mkyong#yahoo.com", "012-111111", "address 789");
users.add(user1);
users.add(user2);
users.add(user3);
}
// Simulate the search function
private List<User> findByUserNameOrEmail(String username, String email) {
List<User> result = new ArrayList<User>();
for (User user : users) {
if ((!StringUtils.isEmpty(username)) && (!StringUtils.isEmpty(email))) {
if (username.equals(user.getUsername()) && email.equals(user.getEmail())) {
result.add(user);
continue;
} else {
continue;
}
}
if (!StringUtils.isEmpty(username)) {
if (username.equals(user.getUsername())) {
result.add(user);
continue;
}
}
if (!StringUtils.isEmpty(email)) {
if (email.equals(user.getEmail())) {
result.add(user);
continue;
}
}
}
return result;
}
}
JS
$(document).ready(function () {
$('#myModal').on('shown.bs.modal', function () {
$('#myInput').focus();
});
$("#search-form").submit(function(event) {
// Disble the search button
enableSearchButton(false);
// Prevent the form from submitting via the browser.
event.preventDefault();
searchViaAjax();
});
});
function searchViaAjax() {
var search = {}
search["username"] = $("#username").val();
search["email"] = $("#email").val();
$.ajax({
type: "POST",
contentType: "application/json",
url: "${home}/search/api/getSearchResult",
data: JSON.stringify(search),
dataType: 'json',
timeout: 100000,
success: function (data) {
console.log("SUCCESS: ", data);
display(data);
},
error: function (e) {
console.log("ERROR: ", e);
display(e);
},
done: function (e) {
console.log("DONE");
enableSearchButton(true);
}
});
}
function enableSearchButton(flag) {
$("#btn-search").prop("disabled", flag);
}
function display(data) {
var json = "<h4>Ajax Response</h4><pre>"
+ JSON.stringify(data, null, 4) + "</pre>";
$('#feedback').html(json);
}
function searchAjax() {
var data = {}
data["query"] = $("#query").val();
$.ajax({
type: "POST",
contentType: "application/json",
url: "${home}search/api/getSearchResult",
data: JSON.stringify(data),
dataType: 'json',
timeout: 100000,
success: function (data) {
console.log("SUCCESS: ", data);
display(data);
},
error: function (e) {
console.log("ERROR: ", e);
display(e);
},
done: function (e) {
console.log("DONE");
}
});
}
Thank you a lot!
"${home}/search/api/getSearchResult" in searchViaAjax seems very odd.
${home} looks like a template string, but it's not being replaced, you can tell since your error message says: "path": "/$%7Bhome%7D/search/api/getSearchResult"

send data from ajax to spring controller

var form_data = {
itemid: globalSourceItem.substr(globalSourceItem.indexOf("-") + 1),
columnName: jqInputs[0].value,
displayName: jqInputs[1].value,
format: jqInputs[2].value,
KBE: jqInputs[3].value,
dgroup: jqInputs[4].value,
dupkey: jqInputs[5].value ,
measurement: jqInputs[6].value ,
times: new Date().getTime()
};
// console.log(form_data);
// console.log($("#tourl").html());
$.ajax({
url: $("#tourl").html(),
type: 'POST',
datatype: 'json',
data: form_data,
success: function(message) {
var j_obj = $.parseJSON(message);
// console.log(j_obj);return false;
if (j_obj.hasOwnProperty('success')) {
toastr.info('Item updated successfully');
setTimeout(function(){
window.location.reload();
},1000);
} else {
toastr.info('There was a problem.');
}
},
error: function(xhr, textStatus, errorThrown)
{
toastr.info('There seems to be a network problem. Please try again in some time.');
}
});
}
Hii friends , this code is working for php and i need to send the same data to the spring mvc through the ajax , can anyone please help me with the exact solution where to make changes as Iam struckup with the same doubt for like 2 weeks...
public class TestController {
#RequestMapping(value = "url", method = RequestMethod.POST)
public ModelAndView action(#RequestBody FormData formData) {
...
}
}
public class FormData {
private String itemid;
public String getItemid() {
return itemid;
}
public void setItemid(String itemid) {
this.itemid = itemid;
}
//...
}
Try sth like this. You should be able to map JSON Object to Java Object.
Maybe you could use annotation #ResponseBody and convert JSONObject to String:
#RequestMapping(value = "/ajax", method = RequestMethod.POST, produces="application/json")
#ResponseBody
public String ajax(#RequestBody ListDataDefinition listDataDefinition) {
System.out.println("id="+listDataDefinition.getItemid());
int i=SchemaDAOI.updateldd(listDataDefinition);
String message="success";
JSONObject obj = new JSONObject();
try {
obj.put("success", "success");
}
catch (JSONException e) {
e.printStackTrace();
}
if(i==1){
System.out.println("success");
}
else{
System.out.println("failure");
}
return obj.toString();
}
}
If you send String to View as ResponseBody and set produces as JSON it should be treated as pure JSON RQ.

How to send boolean result to ajax call

I want to send Boolean result in ajax call.
Ajax call
function myMethod() {
$.ajax({
type : "GET",
url : myurl
dataType : "json",
contentType: "application/json",
crossDomain: true,
success : function(data) {
alert("success :"+data);
},
error : function(data) {
alert("Fialed to get the data");
}
});
}
Controller method from where I want to send Boolean result.
#RequestMapping(value = "/myMethod", method = RequestMethod.GET)
#ResponseBody
public boolean myMethod(empId) {
flag = false;
try {
if (empId != null)
newName = Employee.getName(empId);
else
newName = Employee.getName();
} catch (Exception e1) {
flag = true;
System.out.println("flag :" + flag);
e1.printStackTrace();
}
return flag;
}
i want to send the Boolean flag result to ajax call.
How do i send it. dont mind about the logic .. I just want to know how can i send boolean result to ajax call. Please help .
Ajax uses HTTP which is a text protocol and has no concept of booleans. However, you can return the strings "1" or "0" to represent your boolean values.
Then, in your "success" callback:
success : function ( data ) {
if ( data * 1 ) {
// true result
} else {
// false result
}
}
Without passing the Boolean value to the Ajax call, you can do some thing like this using a map. Using this map you can send anything rather than only limiting to Boolean values.
#RequestMapping(value = "/myMethod", method = RequestMethod.GET)
#ResponseBody
public Map<String, Object> myMethod(empId)
{
flag=false;
try {
if(empId != null)
newName = Employee.getName(empId);
else
newName = Employee.getName();
} catch (Exception e1) {
flag=true;
System.out.println("flag :"+flag);
e1.printStackTrace();
}
final Map<String, Object> map = new TreeMap<String, Object>();
map.put("flagdata", flag);
return map;
}
Then you can access this 'flagdata' object in the Ajax call.
Your Ajax code will be some thing like this.
$.ajax({
type : "GET",
url : myurl
dataType : "json",
contentType: "application/json",
crossDomain:true,
success : function(data) {
alert("success :"+data.flagdata);
},
error : function(data) {
alert("Fialed to get the data");
}
});
Hope it helps.!

Ajax - mvc request always fails

I would like to hit an action in a controller from a view, have it return a result. However I always get a "request failed", then the action code in the controller executes. I am trying to use this in the view:
$("#State").change(function() {
if ($(this).val() != "Va") {
$.ajax({
url: '#Url.Action("ProcessOrder","Checkout")',
type: 'POST',
success: function(result) {
if(result.success) {
alert("good " + result);
} else {
alert("bad " + result);
}
},
error: function() {
alert("request failed");
}
});
} else {
formSwitcher($(this).val());
}
});
And this in the controller:
[AcceptVerbs(HttpVerbs.Post)]
public ActionResult ProcessOrder()
{
string sURL = #"https://someUrl/?OrderId=" + Id ;
var badUrl = string.Empty;
try
{
Response.Redirect(sURL, true);
HttpWebRequest request = null;
HttpWebResponse httpWebResponse = null;
request = HttpWebRequest.Create(sURL) as HttpWebRequest;
request.Method = "GET"; // Supports POST too
httpWebResponse = (HttpWebResponse)request.GetResponse();
return Json(new { success = true });
}
catch (Exception ex)
{
badUrl = "~/Shared/error.aspx";
}
return Json(new { success = false, error = badUrl });
}
What am I doing wrong?
So the problem was Response.Redirect(sURL, true); was throwing an exception which was caught by ajax before it was caught in the try catch. The result was that the ajax said there was a failure, the code continued to run.

Setting up .Net MVC http error codes for ajax calls

I'm trying to setup my controllers so that they can use http error codes to send the responses to ajax calls. So for example I have my login ajax call and controller action:
[System.Web.Mvc.HttpPost, System.Web.Mvc.AllowAnonymous]
public ActionResult Login(string userName, string password, bool rememberMe, string returnUrl)
{
[...]
var loginError = new HttpResponseMessage(HttpStatusCode.Unauthorized)
{
Content = new StringContent("Lorem ipsum 2 " + ErrorMessages.LOGINERROR),
ReasonPhrase = "Lorem ipsum 2 " + ErrorMessages.LOGINERROR
};
throw new HttpResponseException(loginError);
}
$.ajax({
type: "POST",
url: url,
data: data,
dataType: "text",
success: callBack,
error: function () { console.log("Error..."); },
statusCode : {
401: function (result) {
console.log("Login failed (401): " + result);
}
}
});
I'm thinking there are a couple of things I'm not doing right, if someone can point them out that would be lovely!
Thanks!
Look at this solution: ASP.NET MVC Ajax Error handling
Darin Dimitrov write very nice solutions with action filter:
public class MyErrorHandlerAttribute : FilterAttribute, IExceptionFilter
{
public void OnException(ExceptionContext filterContext)
{
filterContext.ExceptionHandled = true;
filterContext.Result = new JsonResult
{
Data = new { success = false, error = filterContext.Exception.ToString() },
JsonRequestBehavior = JsonRequestBehavior.AllowGet
};
}
}
Then you could write your client error handling for all status codes and use it for ajax requests.
Instead of throw exception just return ActionResult that provide some content and setup response code. For your case you can create something that I call ExtendedJsonResult:
public class ExtendedJsonResult : JsonResult
{
public ExtendedJsonResult(object data)
{
base.Data = data;
}
public int StatusCode { get; set; }
public override void ExecuteResult(ControllerContext context)
{
context.HttpContext.Response.StatusCode = this.StatusCode;
base.ExecuteResult(context);
}
}
and then in controller
return new ExtendedJsonResult("Some error")
{
StatusCode = 401,
};
You can also just return existing HttpStatusCodeResult.

Resources