Pass array list back to struts jsp using spring controller? - javascript

Working with two projects, one built on struts and one built on spring. I need to be able to make an ajax call to bring back a list of objects so that I can display them in the html for the struts project. Currently the ajax call to the controller is working correctly but I'm having trouble passing back the array list. Any suggestions?
javascript
$.ajax({
url: 'sampleUrl.com/controller/call',
success: function(data) {
//handle returned object
}
}
Controller method
#RequestMapping(value = 'call', method = RequestMethod.Get)
public #ResponseBody List<SampleObject> getSampleObjects(HttpServletRequest request) {
List<SampleObject> sampleList = new ArrayList<SampleObject>();
sampleList.add(new SampleObject());
return sampleList;
}

In the controller I had to add produces="application/json" to the #RequestMapping and before the return create a new Gson and return gson.ToJson() of the list. On my jsp file I it was able to loop through the list normally once the JSON was returned by adding dataType: 'json' to the ajax call.
javascript
$.ajax({
url: 'sampleUrl.com/controller/call',
dataType: 'json',
success: function(data) {
for(var i = 0; i < data.length; i++) {
console.log(data[i]);
}
}
}
Controller:
#RequestMapping(value = 'call', method = RequestMethod.Get, produces="application/json")
public #ResponseBody String getSampleObjects(HttpServletRequest request)
{
List<SampleObject> sampleList = new ArrayList<SampleObject>();
sampleList.add(new SampleObject());
Gson gson = new Gson();
return gson.toJson(sampleList);
}

Related

Get access to Spring Model variable from JavaScript

How I can get access to variable (which was added as attribute to Model in my controller) in JavaScript and how I can work with properties of it?
My model:
public class Category {
private Long id;
private String name;
private List<Recipe> recipes = new ArrayList<>();
}
My controller:
#RequestMapping(path = "/", method = RequestMethod.GET)
public String showAllCategories(Model model) {
List <Category> categories = categoryService.findAll();
model.addAttribute("categories", categories);
return "index";
}
On my web page I need to show all categories (no problem, using Thymeleaf th:each="category : ${categories}") and have ability add new category to categories variable and set its properties (id, name, recipes for example).
So, how I can get access to variable 'categories' in JavaScript, and how I can add new element and set properties in JavaScript?
You can make an ajax call to this method
// using jquery
$.ajax({
url:'/',
success:function(response){
// get the return pf the method here
// can be assigned to any variable
}
java method change
#RequestMapping(path = "/", method = RequestMethod.GET)
public String showAllCategories(Model model) {
//rest of code
return (the value which which you want to assign to model property);
}
Explore more about ajax
You have to create an API. Rest for example.
The idea is to create methods callable by javascript(via AJAX for example), and do the operations you need to do in java.
Here you have some pseudocode:
#RequestMapping(path = "/addCategory", method = RequestMethod.GET)
public boolean AddCategory(Model model) {
//Do your logic to add category
if (/*everything went good*/) return true;
else return fale;
}
Why you want to use Model?, when you can directly access the object as JSON:
JS Snippet using Angular:
$http.get('/app/get').then(function(response) {
$scope.categoryList = response.data;
}, function(response) {
});
JS Snippet using Jquery:
$.ajax({
url: "/app/get",
type: 'GET',
success: function(response) {
var categoryList = response.data;
console.log(categoryList);
}
});
Java Snippet:
#RestController
#RequestMapping
public class Controller {
#RequestMapping(path = "/get", method = RequestMethod.GET)
public List <Category> showAllCategories() {
return categoryService.findAll();
}
}

making .ajax request to mvc controller - but .done function never executes

So basically Here is what I do:
in body - onload method I call this javascript function
function TestN() {
var list = new Array();
var allElements = document.getElementsByTagName('*');
$("*[wordNum]").each(function ()
{
var endRes = {
ControllerName: this.id,
WordNumber: this.getAttribute("wordNum")
};
list.push(endRes);
});
jQuery.ajax({
url:' #Url.Action("Translate")' ,
contentType: "application/json",
dataType: "json",
data: { List : JSON.stringify(list) }
,
traditional: true
})
}
what it does - it searches all the controlls with attribute "WrdNum" and then I make an ajax request to the MVC Translate action!
In the Translate Action I make a request to a web service which populates a list of type - TranslateModel
public ActionResult Translate(string List)
{
List<TranslateModel>listto = WebServiceBea.TranslateList(1, List);
return View(listto);
}
Also Here is my TranslateModel
public class TranslateModel
{
public string ControllerName { get; set; }
public string WordNumber { get; set; }
public string Description { get; set; }
}
So basically my question is -> what type should I return to a view - > and how to return this list to a javascript or jquery function which has to set the innerHtml property of some html controls with the record from this list.**
I now that it's strange but that's my task
EDIT
Thanks so much for the help. But now I've got another problem:
After I changed my javascript and put. Done method so I could get the data from the server it looks something like this :
$(document).ready(function () {
var list = new Array();
$("*[wordNum]").each(function () {
var endRes = {
ControllerName: this.id,
WordNumber: this.getAttribute("wordNum")
};
list.push(endRes);
});
jQuery.ajax({
url: ' #Url.Action("Translate")',
contentType: "application/json",
dataType: "json",
data: { List: JSON.stringify(list) }
,
traditional: true,
}).done(function (result)
{
alert ("HII") ;
});
});
no matter what I put in the .done function it never executes. It seems like the controller doesn't know where to return the result. |I| don't now. Can something happen from the fact that I'm making this request from the .layout page - on document ready. s
this looks like a greet place to use knockout js.
here is a great step by step for using knockout with the mvc view
so the method will only return json, the view will not have a model just a call to get the json
if you are going to use $.post to pull your data you could return your list as json
[AcceptVerbs(HttpVerbs.Get|HttpVerbs.Post)]
public ActionResult Translate(string List)
{
List<TranslateModel>listto = WebServiceBea.TranslateList(1, modelObj);
return Json(listto);
}
Looking at what you are posting to the action method, it should already be a list of that type. MVC should do the heavy lifting and transform it to the objects you have.
if however you would like to handle the return yourself you can do something like
jQuery.ajax({
url:' #Url.Action("Translate")' ,
contentType: "application/json",
dataType: "json",
data: { List : JSON.stringify(list) },
traditional: true
}).success(function( returnData, returnStatus)
{
//some code to handle the list of objects reutrned
});
You've already got an answer, but consider the following for cases where you may have controller actions called by javascript:
public ActionResult GetItems(string id)
{
var MyList = db.GetItems(id);//returns a list of items
if (Request.IsAjaxRequest())//called from javascript via AJAX
{
return Json(MyList, JsonRequestBehavior.AllowGet);
}
else //regular hyperlink click
{
return View(MyList);
}
}
To use the list, do the following
$.ajax({url: "'#Url.Content("~/controllername/GetItems")?id=' + id"})
.done(function(result){
var mylist = result.responseText.evalJSON();//this is your list of items
for(i=0;i<mylist .length;i++)
{
var myitem = mylist[i];
}
});
NEVERRRR NEVERRR Forge to put jsonRequestBehavior.AllowGet
Thanks alot for everyone for the help

MVC 3 jquery ajax post 2 objects

I have a controller action that takes two objects as arguments. I can't get it to work at all they always come back as null. My latest try looks like below. I have tried many other variations. In this case the FormInfo class is a class with 2 properties that are types for Form1 and Form2. I have also tried having the controller take in the two classes as arguments and the data part looked like { form1: form1Data, form2: form2Data } that was not working as well. I also tried using JSON.stringify to form the data with no luck.
Looking in the network monitor I see the data going back to the server it's just the engine that MVC uses to decode the query string to the objects can't handle what I'm passing back.
Thanks in advance for any information!
ClientSide
var formData = $("#form1").serialize();
var formData2 = $("#form2").serialize();
var formInfo = new Object();
formInfo.FormData = formData;
formInfo.FormData2 = formData2;
$.ajax({
url: 'Controller/Action',
type: 'POST',
data: formInfo,
success: function (data) {
//do stuff
}
});
ServerSide
public ActionResult SaveForms(FormInfo formInfo)
{
//Do Stuff here
}
You could use the a JSON request in conjunction with the .serializeArray() jQuery method. Let's suppose that you have the following model:
public class FormInfo
{
public Form1Data Form1Data { get; set; }
public Form2Data Form2Data { get; set; }
}
where Form1Data and Form2Data are some completely arbitrary complex classes. Now on the client we suppose that you have 2 distinct forms (#form1 and #form2 whose input element names match your complex structures in terms of default model binder wire format). Sending an AJAX request and packing the 2 forms together becomes trivial:
var form1Data = {};
$.each($('#form1').serializeArray(), function () {
form1Data[this.name] = this.value;
});
var form2Data = {};
$.each($('#form2').serializeArray(), function () {
form2Data[this.name] = this.value;
});
$.ajax({
url: '#Url.Action("someaction", "somecontroller")',
type: 'post',
contentType: 'application/json; charset=utf-8',
data: JSON.stringify({
form1Data: form1Data,
form2Data: form2Data
}),
success: function (result) {
// TODO: do something with the result
}
});
And of course the controller action you are POSTing to looks like this:
[HttpPost]
public ActionResult SomeAction(FormInfo formInfo)
{
...
}
I am doing something like this but i have a object and other Formdata to pass my Controller
var discrepancy = self.newCptyReply();
if ($('#UploadFile')[0]) {
var upload = new FormData(),
file = $('#UploadFile')[0].files[0];
upload.append('id', self.globalMessageId());
upload.append('discrepancy', ko.toJSON(discrepancy));
upload.append('doc', file);
}
datacontext.saveCptyToReply(self, upload);
And in controller signature
public ActionResult SaveCptyToReply(Guid id, Trade discrepancy, HttpPostedFileBase doc)
But when it reaches Controller id , doc are ok but discrepancy is null... It has data when funciton is called..
What to do...

Javascript Deserialize is returning the class name instead of actual object

So I'm running GetServerUpdateProgress() in the controller from a $.ajax call on my page. While debugging I can confirm that the variable: myobj is being properly created and filled with the correct data.
But when on the $.ajax success, I'm not getting the data in json format, instead I'm getting
a string of "TrackerMVC.ClassLib.UpdateAJAXProgress" - the objects type.
I've done this in the past with a .svc webservice and didn't have any problems getting the object values using this exact same method.
Any ideas? Thanks!
method:
public UpdateAJAXProgress GetServerUpdateProgress()
{
string BASE_URL = "http://localhost:55094";
string url = BASE_URL + "/Home/UpdateProgress";
WebRequest wr = WebRequest.Create(url);
wr.Credentials = CredentialCache.DefaultNetworkCredentials; // uses current windows user
var myojb = new UpdateAJAXProgress();
var response = (HttpWebResponse)wr.GetResponse();
var reader = new StreamReader(response.GetResponseStream());
JavaScriptSerializer js = new JavaScriptSerializer();
var objText = reader.ReadToEnd();
myojb = (UpdateAJAXProgress)js.Deserialize(objText, typeof(UpdateAJAXProgress));
return myojb; // during debugging this object has the correct values in the correct format
}
class:
public class UpdateAJAXProgress
{
public int Completed { get; set; }
public int Total { get; set; }
}
javascript:
$.ajax({
type: "POST",
async: false,
url: '#(Url.Action("GetServerUpdateProgress","Charts"))',
contentType: "application/json; charset=utf-8",
success: function (data) {
console.log(data); // data being returned is: "TrackerMVC.ClassLib.UpdateAJAXProgress"
},
error: function (XMLHttpRequest, textStatus, errorThrown) {
alert(XMLHttpRequest.status);
alert(XMLHttpRequest.responseText);
}
});
You're misusing MVC.
You should declare your function as returning ActionResult, then return Json(myobj).
If you return a non-ActionResult from an MVC action, MVC will convert it to a string by calling ToString().

Returning json in asp.net webservice

In my application,we use the prototype1.4.2 in the page.
And we need the tree view which support lazy load(make a ajax request and add the data from the server to the node),then I found the
TafelTree
It is built based on the prototype.
And there is a function:
onopenpopulate:
It will load data from the server according the "openlink" provided by user.
Called after a branch is opened. When it's open, it launch an Ajax
request at the page openlink and send the Ajax response to the user
function. It must return a JSON string representing an array of one or
more TafelTreeBranch. Override setOnOpenPopulate() of TafelTree
But it need the server return pure json data format.
And I have created a webservice this way:
[WebService(Namespace = "http://microsoft.com/webservices/";
[WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)]
[ScriptService]
public class UtilService: WebService {
[WebMethod]
[ScriptMethod(ResponseFormat = ResponseFormat.Json)]
public string loadData(id) {
//some logic according the id
return "{id:0,name:'xx'}";
}
}
However when I invoke this service use:
http://xxx/UtilService/loadData?id=0
I always get the xml format.
Through google,it seems that I have to set the "content-type" when make the ajax request.
However,in my case,the ajax is sent by the "TafelTree",I can not add extra parameters.
Any idea? or use another prototype based tree?
you can use jquery to do an Ajax call.
$.ajax({
type: "POST",
contentType: "application/json; charset=utf-8",
url: "webServiceUrl/MethodName",
data: "{Id: '" + id + "'}",
dataType: "json",
success: loadSucceeded,
error: loadFailed,
async: true
});
function loadSucceeded(result, status)
{
var data = result.d;
}
function loadFailed(result, status)
{
}
Note that it is not necessarily to return a string, you can return a list of object.
[WebService(Namespace = "http://microsoft.com/webservices/";
[WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)]
[ScriptService]
public class UtilService: WebService
{
[WebMethod]
public List<string> loadData(id) {
//some logic according the id
return new List<string>(){"data"};
}
}

Categories

Resources