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.
Related
I have a spring web app using thymeleaf on the front end. I have a controller on my backend that adds an item to the database. This same functionality is present across pages so it can be called from multiple urls. When the method is done I would like it redirect to the original url view.
So for example in this method:
#GetMapping(value={"/addBook/{id}")
public String addBookToCart(#PathVariable (value="id") int bookId) {
// database functionality
return "redirect:/"
}
It would always return the redirection to /. But I want to be able to return to the page from where the user pressed the button. Essentially I want the saving to database functionality to happen in the background, without the user necessarily noticing. Is there a way to accomplish that? I was wondering if maybe I should be using POST instead of GET, but this isn't tied to a form, just a url upon clicking a button. Also you still typically return some view in a PostMapping I thought, so I am not sure how that'll solve my problem.
I am new to Web Development.
I am trying to develop a web application using Spring 3. I have my "Hello World" code setup done and is working fine.
Now , in my controller I understand that I can create a Handling method with #RequestMapping annotation that would handle HTTP requests.
My question is, how do I generate a new request (say on click of a specific button) from my jsp page,so that it gets handled by a new method specific to that request in my controller.
One way I think I can do is submit a form like:
<form action="hi">
and handle that form with RequestMapping as:
#RequestMapping(value = "/hi", method = RequestMethod.GET)
Is there any other way to map specific requests from jsp page to specific methods in my controller?
The other way is to use links:
Method invocation
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.
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.
If I can do this, how do I call Java code (methods for instance) from within JavaScript code, in Wicket.
erk. The correct answer would be ajax call backs. You can either manually code the js to hook into the wicket js, or you can setup the callbacks from wicket components in java.
For example, from AjaxLazyLoadPanel:
component.add( new AbstractDefaultAjaxBehavior() {
#Override
protected void respond(AjaxRequestTarget target) {
// your code here
}
#Override
public void renderHead(IHeaderResponse response) {
super.renderHead( response );
response.renderOnDomReadyJavascript( getCallbackScript().toString() );
}
}
This example shows how to add call back code to any Component in Wicket. After the OnDomReady event fires in your browser, when loading a page, Wicket will cause it's js enging, to call back into your code, using Ajax, to the 'respond' method shown above, at which point you can execute Java code on the server, and potentially add components to the ajax target to be re-rendered.
To do it manually, from js, you can hook into wicket's system by printing out getCallbackScript().toString() to a attribute on a wicket component, which you'll then be able to access from js. Calling this url from js manually with wicket's wicketAjaxGet from wicket-ajax.js.
Check out the mailing list for lot's of conversation on this topic:
http://www.nabble.com/Wicket-and-javascript-ts24336438.html#a24336438
Excerpt from https://cwiki.apache.org/WICKET/calling-wicket-from-javascript.html
If you add any class that extends AbstractDefaultAjaxBehavior to your page, wicket-ajax.js will be added to the header ofyour web page. wicket-ajax.js provides you with two basic methods to call your component:
function wicketAjaxGet(url, successHandler, failureHandler, precondition, channel)
and
function wicketAjaxPost(url, body, successHandler, failureHandler, precondition, channel)
Here is an example:
JavaScript
function callWicket() {
var wcall = wicketAjaxGet('$url$' + '$args$', function() { }, function() { });
}
$url$ is obtained from the method abstractDefaultAjaxBehavior.getCallbackUrl(). If you paste the String returned from that method into your browser, you'll invoke the respond method, the same applies for the javascript method.
You can optionally add arguments by appending these to the URL string. They take the form &foo=bar.
you get the optional arguments in the Java response method like this:
Map map = ((WebRequestCycle) RequestCycle.get()).getRequest().getParameterMap();
or this:
String paramFoo = RequestCycle.get().getRequest().getParameter("foo");
http://www.wicket-library.com/wicket-examples-6.0.x/index.html/ has plenty of examples to get you going.
Or have a Have a look at DWR
http://directwebremoting.org/
DWR allows Javascript in a browser to interact with Java on a server and helps you manipulate web pages with the results.
As Dorward mentioned this is done via AJAX
Assuming you mean JavaScript running on the client - you cause an HTTP redirect to be made to the server, and have your servlet react to the request for the given URL.
This is known as Ajax, and there are a number of libraries that help you do it..