I try to send ajax request in my SpringMVC project.
$.ajax({
contentType : 'application/json; charset=utf-8',
type : 'get',
url : 'order/get/'+i,
dataType : 'json',
data : {},
success : function(result) {
alert("Successfully!");
},
error : function(result, status, er) {
alert("error: "+result+" status: "+status+" er:"+er);
}
});
#RequestMapping(value = "/order/get/{id}", method = RequestMethod.GET)
public ResponseEntity<Order> getOrder(
#PathVariable("id") long id) {
Order order = orderService.getOrderById(id);
if (order == null) {
new ResponseEntity<Order>(HttpStatus.NOT_FOUND);
}
return new ResponseEntity<Order>(order, HttpStatus.OK);
}
But I always get error.
In controller method return object of 'order', but ajax throws 'GET net::ERR_CONNECTION_RESET'.
Why ?
The problem was that the Order entity serialized to JSON with all the attributes, including those that marked as #ManyToOne. This serialization Json was excessive, and the response was very huge. The entity class Order, had to designate attributes such annotation #JsonIgnore. After this error is gone and the answer is processed normally.
Related
I am trying ajax Javascript Map, to spring controller. but it's getting null in backend. Please excuse if i am repeating question.
I can't change Map type, as my whole front end logic on it. Because set, get and has method from Map is what I need.
var ansMap = new Map(); // This way i created object
// added many values in ansMap,
$.ajax({
type: "POST",
url: myUrl,
contentType : 'application/json',
//cache: false,
dataType : 'json',
data : ansMap, // can't JSON.stringy(ansMap) as it gives empty json
success: function(result) {
console.log(result);
},
Spring code
#RequestMapping (value="myUrl", method=RequestMethod.POST)
public #ResponseBody String saveData(#RequestParam(required = false, value = "mapData") Map<String,List<String>> mapData, Model map)
{
log.info("Call Success");
log.info("mapData: "+mapData);
Please suggest what needs to be done here.
You can actually send your Map without mutating the value
var ansMap = new Map(); // This way i created object
// added many values in ansMap,
$.ajax({
type: "POST",
url: myUrl,
contentType : 'application/json',
//cache: false,
dataType : 'json',
data : JSON.stringify(Object.fromEntries(ansMap)), // can't JSON.stringy(ansMap) as it gives empty json
success: function(result) {
console.log(result);
},
That will turn it into a javascript object.
Object.fromEntries Will turn you Map into a javascript object, without altering the original Map
Regarding your backend i think you mis-interpret the #RequestParam annotation
The #RequestParam is to extract query parameters, form parameters and even files from the request.
I think that what you are looking for is #RequestBody.
Meaning you would be looking for something similar to :
#RequestMapping(value="/myUrl",method = RequestMethod.POST)
public String saveData( #RequestBody Map<String,Object> body) {
This should work
page
<button id="doPost"> post </button>
<script>
$(function () {
var map = new Map();
map.set('CIQ_2','aa');
map.set('CIQ_3','78965412300');
console.log(map);
$("#doPost").click (function() {
var settings = {
beforeSend: function(xhr, options) {
xhr.setRequestHeader("content-type" ,"application/json; charset=utf-8");
},
type: 'POST',
url: '/post' ,
data: JSON.stringify(Object.fromEntries(map))
}
$.ajax(settings).done(function(result) {
console.log("done : " + result);
});
});
});
</script>
Controller
#PostMapping("/post")
#ResponseBody
public String post(#RequestBody Map<String,String> data) {
System.out.println(data);
return "data well received";
}
will print
{CIQ_2=aa, CIQ_3=78965412300}
working code on GitHub
I'm working on an ASP.NET MVC 4 website and I've got some troubles with a functionality. I explain, I've to select entities displayed in a table with their linked checkbox :
Screenshot of my table where each row has a checkbox with the same Id as the entity
Console showing updates in the array
Inside my script I have been abled to store each checked Id's checkbox in an array and remove those if the checkbox is unchecked. But I can't pass the array to my controller's function to delete each selected entity in the database.
I used $.ajax() from jquery to send through a POST request the array (as JSON) but I always get 500 error :
JSON primitive invalid
Null reference
Here's my function in my script (I don't know if my array's format is valid) :
var sendDocsToDelete = function (docsArray) {
$.ajax({
type: 'POST',
url: 'Main/DeleteDocuments',
data: JSON.stringify(docsArray),
contentType: 'application/json; charset=utf-8',
datatype: 'json',
success: function (result) {
alert('Success ' + result.d);
},
error: function (result) {
alert('Fail ' + result.d);
}
});
}
Then, the POST call the following function in my controller :
[Authorize]
[WebMethod]
public void DeleteDocuments(string docsToDelete)
{
int id;
string[] arrayDocs = JsonConvert.DeserializeObject<string[]>(docsToDelete);
foreach (string docId in arrayDocs)
{
int.TryParse(docId, out id);
dal.DeleteDocument(id); // dal = DataAccessLayer is the class which interacts with the database by executing queries (select, delete, update...)
}
}
Update 2
[Authorize]
public ActionResult DeleteDocuments(int[] docsToDelete)
{
try{
foreach (string docId in arrayDocs)
{
int.TryParse(docId, out id);
dal.DeleteDocument(id); // dal = DataAccessLayer is the class which interacts with the database by executing queries (select, delete, update...)
}
return Json("Success");
}
catch
{
return Json("Error");
}
}
var sendDocsToDelete = function (docsArray) {
$.ajax({
type: 'POST',
url: 'Main/DeleteDocuments',
data: docsArray,
contentType: 'application/json; charset=utf-8',
datatype: 'json',
success: function (result) {
alert('Success ' + result.d);
},
error: function (result) {
alert('Fail ' + result.d);
}
});
}
Any ideas about this issue ? I hoped I was clear enough. Do not hesitate if you need more details.
If you are passing an integer array properly from $.ajax (i.e. your docsArray should be having value like [15,18,25,30,42,49]) then you should try :
[Authorize]
public ActionResult DeleteDocuments(int[] docsArray)
{
//int id;
//string[] arrayDocs = JsonConvert.DeserializeObject<string[]>(docsToDelete);
try {
foreach (int docId in docsArray)
{
//int.TryParse(docId, out id);
dal.DeleteDocument(docId); // dal = DataAccessLayer is the class which interacts with the database by executing queries (select, delete, update...)
}
return "Success ";
}
catch {
return "Error";
}
}
Update :
Your javascript code should be :
var sendDocsToDelete = function (docsArray) {
$.ajax({
type: 'POST',
url: 'Main/DeleteDocuments',
data: JSON.stringify(docsArray),
contentType: 'application/json; charset=utf-8',
datatype: 'json',
success: function (result) {
alert('Success ');
},
error: function (result) {
alert('Fail ');
}
});
}
Maybe the datatype in the JSON array is not a string? (This could happen if you have an array in the form of [45,64,34,6], or a mixed one like [345,"wef4"]).
To make sure something is a string in Javascript you can do this: var string = "".concat(otherVar);
Try changing your ajax data to something like this..
data : JSON.stringify({'docsToDelete':docsArray}),
Make these changes to your code.
In Jquery
data: docsArray, no need to stringify the array
In Controller
[Authorize] //remove [WebMethod]
public ActionResult DeleteDocuments(string[] docsToDelete) //Add ActionResult, Change parameter to accept array
{
int id;
string[] arrayDocs = docsToDelete; //no need of deserilization
foreach (string docId in arrayDocs)
{
int.TryParse(docId, out id);
dal.DeleteDocument(id); // dal = DataAccessLayer is the class which interacts with the database by executing queries (select, delete, update...)
}
return Json(id); //return id back to ajax call...
}
Can you tell me what it's going wrong with the following ajax call to controller ?
The controller that is called via ajax :
#RequestMapping(value = "/userManagement/loadData.html", method = RequestMethod.POST,produces="text/plain")
public #ResponseBody String loadData(#RequestBody String jsonData) {
try {
Map<String, Object> data = JsonUtils.jsonAsMap(jsonData);
pageSize = Integer.valueOf(data.get("pageSize").toString());
pageNumber = Integer.valueOf(data.get("pageNumber").toString());
} catch (Exception e) {
return "failure";
}
return "success";
}
The ajax function :
function reloadUsers(){
$.ajax({
type : "POST",
cache : false,
dataType: 'json',
contentType: 'application/json',
mimeType: 'application/json',
url : "userManagement/loadData.html",
data : JSON.stringify({
pageSize : 10,
pageNumber : 0
}),
success : function(response) {
if(response.responseText=='true'){
console.log('success');
}else{
console.log('server error');
}
},
error : function(jqxhr){
console.log('error');
console.log(jqxhr.responseText);
}
});
}
Now when i execute the ajax call to the controller it always goes on the error function and the jqxhr.responseText is always the value returned by the controller(in this case 'success' or 'failure'.
My question is why is this happening ?
If i change the controller returned values to "true" or "false" the ajax successfully callback the 'success' function.
I also tried with produces="application/json"and got the same result.
Change the datatype to:
dataType: 'text',
As you are going to get a string in response because of this:
#RequestMapping(value = "/userManagement/loadData.html", ....... produces="text/plain")
//--------because of this-----------------------------------^^^^^^^^^^^^^^^^^^^^^^
Longer title would be:
"Attempts to use an ajax call to the controller to insert search results into a table result in errors while remaining on the same page results in "405" or "Direct self-reference leading to cycle... " errors"
I am trying to find a way to fill a table with search result while staying on same page using an ajax call to the controller.
ajaxCall->Controller->Service(completes search)->Controller(result from search)->back to ajax with response
I have an ajax call that is triggered on form submit after prevent default:
function ajaxGetSearchResults(link, form) {
var myList=[];
var jqxhr = $.ajax({
"url" : link,
"data" : form.serialize(),
"dataType" : 'json',
"type" : "POST",
"headers": {
'Content-Type': 'application/json'
},
"success" : function (response){
console.log("Ajax success");
fillTable(response);
console.log("Search results added to table: "+response);
},
"complete": function(response){
console.log("Ajax call to controller completed");
},
"error": function(){
console.log("Ajax call to controller triggered error");
}
});
}
In the controller I recieve the ajax request as such:
#RequestMapping(value = "/ajaxScriptSearch", method = RequestMethod.POST)
public #ResponseBody List<ResultViewDto> processAJAXRequestSearch(#RequestParam String a1,
#RequestParam String a2, #RequestParam String a3, #RequestParam String a4) {
SearchDto searchDto = new SearchDto();
searchDto.setAttribute1(a1);
searchDto.setAttribute2(a2);
searchDto.setAttribute3(a3);
searchDto.setAttribute4(a4);
try {
/*
calling Service, performing search using searchDto as a parameter, mapping result to resultViewDtos
*/
} catch(Exception e){
/* do something */
}
return resultViewDtos;
}
The call to the service is successfull.
An example of resultViewDtos would be: [viewDto1, viewDto2, viewDto3] where every view dto contains a number of string values which need to be inserted into a table.
I seem to be getting a "HTTP Status 405 - Request method 'GET' not supported" error, but my ajax call is "type: POST".
When I tried doing it with GET insted, I get an "Direct self-reference leading to cycle (through reference chain...)" error.
I am using jackson-core 2.6.2, jackson-databind 2.6.2, Spring 4, Hibernate 4.
I would appericiate any help I can get...
In the end I managed to create a workaround for this.
I have changed my ajax call as such:
function ajaxGetSearchResults(link, form) {
var jqxhr = $.ajax({
"url" : link,
"data" : form,
"dataType" : 'json',
"headers": {
'Accept' : 'application/json',
'Content-Type': 'application/json'
},
"type" : "GET",
"success" : function (response) {
console.log("Ajax success");
fillTable(response);
},
"complete": function(response) {
console.log("Ajax call to controller completed");
},
"error": function() {
console.log("Ajax call to controller triggered error");
}
});
}
And my controller as follows:
#RequestMapping(value = "/ajaxScriptSearch", method = RequestMethod.GET)
public #ResponseBody List<String> processAJAXRequestSearch(#RequestParam String a1,
#RequestParam String a2, #RequestParam String a3, #RequestParam String a4) {
SearchDto searchDto = new SearchDto();
searchDto.setAttribute1(a1);
searchDto.setAttribute2(a2);
searchDto.setAttribute3(a3);
searchDto.setAttribute4(a4);
List<String> result = new ArrayList<String>();
List<ResultViewDto> resultViewDtos = new ArrayList<ResultViewDto>();
try {
/*
calling Service, performing search using searchDto as a parameter, mapping result to resultViewDtos
*/
for(int i=0; i<resultViewDtos.size(); i++){
result.add(resultViewDtos.get(i).toResponseString()); //a new method
}
} catch(Exception e){
/* do something */
}
return result;
}
toResponseString() is a new method I have created in my resultViewDto that returns a string in which the attributes I need are separated by ":".
After filling the result and sending it back to ajax as a response, I then split the recieved response first on (',') to get the individual "rows" equivalent to a single resultViewDto, and then by (':') to get the values for each cell.
There might be a better way of solving it, but this woked like a charm.
I hope this will be usefull for someone else too.
I have a Home controller whose view has a button.I want to call a controller named SearchSpace on button click.
View :
<script type="text/javascript">
var data = { "id": "1" }
function search() {
alert("hello" + JSON.stringify(data));
$.ajax({
url: '/SearchSpace/searchSpace',
type: 'POST',
dataType: "json",
contentType: 'application/json',
data: JSON.stringify(data),
success: function (returnPayload) {
console && console.log("request succeeded");
},
error: function (xhr, ajaxOptions, thrownError) {
console && console.log("request failed");
}
});
}
</script>
Controller
[HttpGet]
public ActionResult searchSpace()
{
return View();
}
[HttpPost]
public ActionResult searchSpace(SearchSpace search)
{
//code
return View();
}
Route Config
public class RouteConfig
{
public static void RegisterRoutes(RouteCollection routes)
{
routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
routes.MapRoute(
name: "Default",
url: "{controller}/{action}/{id}",
defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional }
);
}
}
alert is calling but it is not moving to SearchSpace Controller..
Please help me.
try this
<button id="click">Click me
</button>
Problem is with data type that jQuery.ajax() is expect, since you assign dataType property with json. From jQuery API documentation:
dataType (default: Intelligent Guess (xml, json, script, or html))
Type: String
The type of data that you're expecting back from the server. If none is specified, jQuery will try to infer it based on the MIME type of the response (an XML MIME type will yield XML, in 1.4 JSON will yield a JavaScript object, in 1.4 script will execute the script, and anything else will be returned as a string). The available types (and the result passed as the first argument to your success callback) are:
..."json": Evaluates the response as JSON and returns a JavaScript object. The JSON data is parsed in a strict manner; any malformed JSON is rejected and a parse error is thrown. As of jQuery 1.9, an empty response is also rejected; the server should return a response of null or {} instead. (See json.org for more information on proper JSON formatting.)
There are at least 2 ways to solve the problem:
First, Omit dataType property:
$.ajax({
url: '/SearchSpace/searchSpace',
type: 'POST',
contentType: 'application/json',
//dataType: "json", << delete this line or comment it
data: JSON.stringify(data),
success: function (data) {
console && console.log(data);
},
error: function (xhr, ajaxOptions, thrownError) {
console && console.log("request failed");
}
});
Second, return JSON type data from response:
[HttpPost]
public ActionResult searchSpace(int? id)
{
if (Request.IsAjaxRequest() && id != null)
{
return Json(new { data = "Requested data is: " + id.ToString() });
}
return View();
}