I am calling the controller from a plane jsp page with out form submit using ajax and I want to return a hashmap from controller to the jsp page which i can iterate to show the values of hashmap.
If I am sending a message in the response , I can get that in the ajax function inside success: but how to get the whole map. Because if you even set in the request attribute you can't get that in the jsp page.Kindly help.
Use #ResponseBody annotation on your controller's method. For e.g.:
#RequestMapping(value = "/yourAjaxRequestUrl", method = RequestMethod.POST)
public
#ResponseBody
Map<String, Object> performOperation(#RequestParam("someParam") String someParam) {
//Do something
return Collections.<String, Object>singletonMap("yourObject", yourObject);
}
This will return you an object in JSON format, all objects in your map then can be accessed via javascript.
I think you're confusing your server-side code with your client-side code. AJAX is client side, JSPs are server side. You just cannot pass data between the two.
When you're making your AJAX call, the JSP has already finished execution, and the markup it produced is there in the browser, including your AJAX code.
If your Spring Controller is returning JSON (maybe you're representing your Map as a JavaScript associative array), then you can use jQuery to iterate over that array and create dynamic HTML elements according to its contents.
Related
I want to pass a preformed JSON string from a Spring MVC controller method using the ModelMap.addAttribute or put method. I have some data that needs to be loaded when the page renders. I do not want to send a Java object list and then have to unpack it with Javascript into JSON. The problem is that ModelMap.addAttribute or ModelMap.put seems to convert the JSON string back into the Java objects.
When I inspect the added attribute in the JSP I get things like:
[foos.web.FOOSController$foosDataHolder#63eef378,foos.web.FOOSController$foosDataHolder#5f395275]
In controller:
model.put("foosData", jsonFoosString); // can I just pass a string here?
In JSP:
var foosData = "${foosData}";
Then the JSON parser in the browser cannot parse foos.web.FOOSController$foosDataHolder#63eef378 and says that '#' is an invalid character, which it is.
Thanks for any suggestions for this Spring MVC novice.
I know that I could do an ajax method and get the JSON string back, or unpack an object array in the JSP, but I want this to be fast.
I would like to call a controller method using a button on a JSP page in Spring MVC, but I would like it to stay on a current page, don't reload it or anything, simply call a method. I found it difficult. My button is on cars.jsp page. In order to stay on this page I have to do something like this:
#RequestMapping(value="/start")
public String startCheckingStatus(Model model){
System.out.println("start");
model.addAttribute("cars", this.carService.getCars());
return "car\\cars";
}
button:
Start
But this is not a good solution because my page is actually reloaded. Can I just call controller method without any refreshing, redirecting or anything? When I remove return type like so:
#RequestMapping(value="/start")
public void startCheckingStatus(Model model){
System.out.println("start");
}
I got 404.
Add an onclick event on your button and call the following code from your javascript:
$("#yourButtonId").click(function(){
$.ajax({
url : 'start',
method : 'GET',
async : false,
complete : function(data) {
console.log(data.responseText);
}
});
});
If you want to wait for the result of the call then keep async : false otherwise remove it.
As mentioned elsewhere you can achieve this by implementing an Ajax based solution:
https://en.wikipedia.org/wiki/Ajax_(programming)
With Ajax, web applications can send data to and retrieve from a
server asynchronously (in the background) without interfering with the
display and behavior of the existing page. By decoupling the data
interchange layer from the presentation layer, Ajax allows for web
pages, and by extension web applications, to change content
dynamically without the need to reload the entire page.
To achieve this you will need to make changes to both the client and server side parts of your app. When using Spring MVC it is simply a case of adding the #ResponseBody annotation to your controller method which:
can be put on a method and indicates that the return type should be
written straight to the HTTP response body (and not placed in a Model,
or interpreted as a view name).
http://docs.spring.io/spring/docs/current/spring-framework-reference/html/mvc.html#mvc-ann-responsebody
Thus, for example, to return a simple String in the Ajax response we can do the following (without the #ResponseBody the framework would try and find a view named 'some status' which is obviously not what we want):
#RequestMapping(value="/start")
#ResponseBody
public String startCheckingStatus(Model model){
return "some status";
}
For the client part you need to add some javascript which will use the XMLHttpRequest Object to retrieve data from your controller.
While there are various frameworks which can simplify this (e.g. JQuery) there are some examples at the below using vanilla javascript and it might be worth looking at some of these first to see what is actually going on:
http://www.w3schools.com/ajax/ajax_examples.asp
If we take this specific example:
http://www.w3schools.com/ajax/tryit.asp?filename=tryajax_callback
and [1] copy the <button/> and <script/> elements to your JSP, [2] change the URL to point to your controller and, [3] create an element <div id="demo"></div> in your JSP then, on clicking the button in your page, this <div/> should be updated to display the String returned by your controller.
As noted this is a lot of code for one action so you can use some JS framework to abstract a lot of it away.
I've been having a problem regarding using AJAX with Spring MVC. I have a form which has a lot of fields, and each field retrieves data depending on the associated button that was clicked.
So, each one of my buttons needs to call an AJAX request. Each response will be displayed on the associated field.
I wonder if it is possible to call a different method in my Spring controller once I clicked on a different button?
In other words, I want to make multiple ajax requests to the same controller where each request will call a different method in that same controller.
See this example :
// when get account detail is clicked it will call this method
#RequestMapping(method=RequestMethod.POST)
public #ResponseBody String getAccountDetails(#RequestParam(value="accountid") String accountid){
return somefunct.getAccountDetails(accountid);
}
// when get account summary is clicked it will call this method
#RequestMapping(method=RequestMethod.POST)
public #ResponseBody String getAccountSummary(#RequestParam(value="accountid") String accountid){
return somefunct.getAccountSummary(accountid);
}
/* when submit button is clicked... Form is submitted for saving*/
#RequestMapping(method=RequestMethod.POST)
public String submitForm(){
// save here
return "myform";
};*/
Currently, I can have only one AJAX request. How can I modify this code so that I can have different functionality for different AJAX requests?
First, consider that when you retrieve data from a server without modifying the state of that server, the commonly accepted standard is to use the HTTP GET method, not POST. Thus, for your first two methods, you are misusing the HTTP Methods.
Second, you can map individual URL patterns to a specific method using the value property of the RequestMapping annotation.
Third, the most RESTful way to represent your account details resource is to use the PathVariable annotation and include your identifying accountid in the actual path:
#RequestMapping(value="/account/{accountid}/details", method = RequestMethod.GET)
public #ResponseBody String getAccountDetails(#PathVariable(value="accountid") String accountid){
return somefunct.getAccountDetails(accountid);
}
Next, you can represent your account summary using a different URL pattern where the URL is built like a tree, where the first two parts of the path are once again "Account" and the accountid:
// when get account summary is clicked it will call this method
#RequestMapping(value="/account/{accountid}/summary", method=RequestMethod.GET)
public #ResponseBody String getAccountSummary(#PathVariable(value="accountid") String accountid){
return somefunct.getAccountSummary(accountid);
}
Now, your submit method, on the other hand, has side effects. This is just a fancy way of saying that the state of your server will be different at the end of this request, and any GET requests made to that resource will be different than they were prior to the change. The appropriate HTTP method to use when modifying a resource or adding a resource to a collection is the HTTP POST Method. When replacing a collection, the HTTP Method PUT is the generally accepted method of choice.
Another differentiating factor between PUT and POST is that PUT is idempotent, meaning that the same request repeated over and over again doesn't change the state on the server. If hitting the same request multiple times creates more records, then use POST.
Lastly, this request can be mapped to a URL as well. In the example below, I've assumed you are creating a new Account record and inserting a new record in the collection of accounts in the database. Thus, I've used POST. I also modified your parameter list to use PathVariable to take the accountid from the URL path, and I added a RequestBody annotation so that you can send an object in the body of the request, which could be deserialized into a Java object:
/* when submit button is clicked... Form is submitted for saving*/
#RequestMapping(value="/account/{accountid}", method=RequestMethod.POST)
public String submitForm(#PathVariable String accountid, #RequestBody Account account){
// save here
return "myform";
}
For more information on Spring MVC, please check out the Spring documentation on Spring MVC.
How do to pass a ArrayList of Array from Jsp to spring controller.
I want my user fill some form in which 1 object data is entered in many way. What I want to make a list and save all the different values of that object.
Then i want to pass it to spring controller. What is the best way for this? Thanks.
Yes, Create Class and bind the this class to form so the controller will automatically receive the class.
It will look something like this.
#RequestMapping(value="/submit",method = RequestMethod.POST)
public ModelAndView addUser(#Valid MyClass myClass, BindingResult result){
}
public class MyClass{
private List<ArrayList<Integer>> list = new ArrayList<ArrayList<Integer>>();
//getters and setters.
}
hope it helps.
Update:
Ajax way:
JSON = {"myClass" "list":[[1,2,3,4],[1,2,3,45],[3,5,1]]}
and the Controller itself.
#RequestMapping(value="/submit",method = RequestMethod.POST)
#ResponseBody
public String getAjax(#RequestBody Myclass myClass){
//do something
}
and the use javascript to build suck JSON and send it to server using AJAX. You can validate your form before that using Javascript as well.
First of all, you'll be passing an HTTP request from a JSP to a Spring controller, not an array of arrays.
The form that your users fill out will have HTML form elements that will be sent to the server side as HTTP parameter name/value pairs.
The Spring controller will validate and bind the form elements into objects; you can certainly bind all those parameters into an array of arrays if you wish.
I am using Starbox in my Spring page. I want to submit the user rating so I can store it in the database and not have to refresh the page for the user. How can I have a Spring controller that accepts this value and doesn't have to return a new view. I don't necessarily need to return any updated html - if the user clicks the Starbox, that is all that needs to happen.
Similarly, if I have a form with a submit button and want to save the form values on submit but not necessarily send the user to a new page, how can I have a controller do that? I haven't found a great Spring AJAX tutorial - any suggestions would be great.
If you use annotations, perhaps the more elegant way to return no view is to declare a void-returning controller method with #ResponseStatus(HttpStatus.OK) or #ResponseStatus(HttpStatus.NO_CONTENT) annotations.
If you use Controller class, you can simply return null from handleRequest.
To post a from to the controller via AJAX call you can use the appropriate features of your client-side Javascript library (if you have one), for example, post() and serialize() in jQuery.
The AJAX logic on the browser can simply ignore any data the server sends back, it shouldn't matter what it responds with.
But if you really want to make sure no response body gets sent back, then there are things you can do. If using annotated controllers, you can give Spring a hint that you don't want it to generate a response by adding the HttpServletResponse parameter to your #RequestMapping method. You don't have to use the response, but declaring it as a parameter tells Spring "I'm handling the response myself", and nothing will be sent back.
edit: OK, so you're using old Spring 2.0-style controllers. If you read the javadoc on the Controller interface, you'll see it says
#return a ModelAndView to render, or
null if handled directly
So if you don't want to render a view, then just return null from your controller, and no response body will be generated.