send data from ajax to spring controller - ajax

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.

Related

How return a empty JSON in Spring MVC?

I'm using ajax with GET method, I'm waiting receive a JSON but sometime the response is null and get the error:
SyntaxError: Unexpected end of JSON input
ajax:
$(document).ready(function() {
$("#form_data").submit(function(e) {
e.preventDefault()
var expediente = $('#expediente').val();
$.ajax({
url : 'buscarPaciente' + '?expediente=' + expediente,
dataType : "json",
type : "GET",
contentType : 'application/json',
mimeType : 'application/json',
success : function(data) {
console.log(data.nombre);
},
error : function(xhr, status, error) {
console.log(error)
}
});
})
});
in the controller:
#RequestMapping(value="/buscarPaciente", method = RequestMethod.GET)
public #ResponseBody MntPaciente
buscarPaciente(#RequestParam("expediente") String expediente) {
MntPaciente mntPaciente = servicePx.findByexpediente(expediente);
if (mntPaciente!= null) {
return mntPaciente;
}
return null; // Should I return an empty json? how?
}
There are several ways to do it. The first is to configure the JSON library that used to serialise JSON .In case of Jackson , you can use #JsonInclude to exclude all the empty properties not to serialise and just return an empty MntPaciente :
#JsonInclude(Include.NON_EMPTY)
public class MntPaciente {
}
public #ResponseBody MntPaciente buscarPaciente(#RequestParam("expediente") String expediente) {
....
return new MntPaciente();
}
To apply globally rather to configure for each object , you could use
ObjectMapper om = new ObjectMapper();
om.setSerializationInclusion(Include.NON_EMPTY);
The other way is to change the controller method to return ResponseEntity and directly return a empty JSON string :
public #ResponseBody ResponseEntity buscarPaciente(#RequestParam("expediente") String expediente) {
if (mntPaciente!= null) {
return ResponseEntity.of(mntPaciente);
}else{
return ResponseEntity.of("{}");
}
}

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"

NullReferenceException showing for ValidateAntiForgeryToken in MVC 5

I'm trying to save data using ajax in MVC 5. When I'm posting form data without #Html.AntiForgeryToken(), it's working nicely. But it's showing me Object reference not set to an instance of an object error for using #Html.AntiForgeryToken(). Here is my ajax code:
$.ajax({
type: "POST",
url: "/Employees/Create",
data: data,
async: false,
success: function (result) {
if (result == 1) {
window.location.href = '/Employees';
}
else {
$('#error-span').html('Error in insert.');
}
},
error: function () {
alert('Failed');
}
});
Here is my controller method:
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Create([Bind(Include = "Address,JoinDate,DoB,Gender,BloodGroup,Email,LastName,FirstName,Mobile,UpdateDate,UpdatedBy,Status,EmployeeType,CreatedBy,CreateDate,DesignationId")] EmpDetail empDetail)
{
try
{
Regex rgx = new Regex("[^a-zA-Z0-9 - .]");
empDetail.FirstName = CultureInfo.CurrentCulture.TextInfo.ToTitleCase(rgx.Replace(empDetail.FirstName, "").ToLower()).Trim();
empDetail.LastName = CultureInfo.CurrentCulture.TextInfo.ToTitleCase(rgx.Replace(empDetail.LastName, "").ToLower()).Trim();
empDetail.Email = empDetail.Email.ToLower().Trim();
empDetail.UpdateDate = DateTime.Now;
empDetail.CreatedBy = 234;
empDetail.CreateDate = DateTime.Now;
empDetail.UpdatedBy = 234;
empDetail.Status = 1;
if (ModelState.IsValid)
{
db.EmpDetails.Add(empDetail);
db.SaveChanges();
return Json(1);
}
else
{
return Json(2);
}
}
catch (Exception e)
{
return Json(e.Message);
}
}
This is happening because the data is being sent via JSON instead of HTML Form data. You should try to pass the token in the headers. For example:
View:
<script>
#functions{
public string TokenHeaderValue()
{
string cookieToken, formToken;
AntiForgery.GetTokens(null, out cookieToken, out formToken);
return cookieToken + ":" + formToken;
}
}
$.ajax("api/values", {
type: "post",
contentType: "application/json",
data: { }, // JSON data goes here
dataType: "json",
headers: {
'RequestVerificationToken': '#TokenHeaderValue()'
}
});
</script>
Controller:
void ValidateRequestHeader(HttpRequestMessage request)
{
string cookieToken = "";
string formToken = "";
IEnumerable<string> tokenHeaders;
if (request.Headers.TryGetValues("RequestVerificationToken", out tokenHeaders))
{
string[] tokens = tokenHeaders.First().Split(':');
if (tokens.Length == 2)
{
cookieToken = tokens[0].Trim();
formToken = tokens[1].Trim();
}
}
AntiForgery.Validate(cookieToken, formToken);
}
Source: https://www.asp.net/web-api/overview/security/preventing-cross-site-request-forgery-csrf-attacks

Spring 4 Jackson Hashmap to Json losing ordering of keys

I am using Spring 4 and Jackson. I am trying to return a LinkedHashMap from controller to Ajax Response.
However when Jackson is converting it to JSON the order of keys in the LinkedHashMap is getting lost.
How can I maintain the order of records.
Controller code:
#ResponseBody
#RequestMapping(value = "/getLevel2", method = RequestMethod.POST)
public LinkedHashMap<String, String> getLevel2(HttpServletRequest request)
{
System.out.println("In getLevel2"+request.getParameterNames());
String catId=request.getParameter("catId");
String fkey=request.getParameter("key");
LinkedHashMap<String, String> h=categoryService.getCategoryLevel2Map(2100,fkey);
System.out.println(h);
return h;
}
Ajax call:
var jqxhr = $.ajax({
type: "POST",
url:"/a2bNext/getLevel2",
cache: false,
data:'catId='+ catId+'&key='+selectedValue
} )
.done(function(data) {
$("#level2").empty();
for (var key in data) {
value=data[key];
isLeaf=value.split('::')[1];
value=value.split('::')[0];
if(isLeaf==1)
{
option = $('<option></option>').attr("value", key).text(value);
$("#level2").append(option);
}
else
{
option = $('<option></option>').attr("value", key).attr("class","subdivide").text(value);
$("#level2").append(option);
}
}
$("#level2").show();
})
.fail(function() {
alert( "error1" );
})
.always(function() {
//alert( "complete" );
});
});
Could anyone suggest how can I get the keys in ajax response in the same order as in LinkedHashMap.

how to call ajax success and error function from controller?

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);

Resources