How do I call Java code from JavaScript code in Wicket? - java

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..

Related

Call controller method from JSP button in Spring MVC

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.

How to pass javascript variable in jstl function to managed bean?

I want to use javascript value in jstl function on jsp page which call function in managedbean. anyone help.
Javascript code:
alert(document.getElementById('data').value);
'${mapBean.testfunc(document.getElementById('data').value)}';
managedbean:
public void testfunc(String a) {
System.out.println("my function test is printed"+a);
}
I don't work with JSP, but I don't think this is possible. Websites use a Client-Server-Model. The Java-Code (Beans) are executed on the server, the Javascript-Code is executed in the browser on the client (AFTER the website already left the server).
To communicate back from javascript-code on a webpage to the server, you have to use AJAX-Calls. This is a new HTTP-Request which doesn't reload the page but gets processed by your own javascript-code.
Maybe this tutorial can help you: http://howtodoinjava.com/2013/06/21/complete-ajax-tutorial/

Converting a Java program with main method into a servlet

I am new to servlets. I have a query processor java program and now, I want to use it in a Web Application. I have an interface(HTML) which generates the query and I want to run the program on a button click in the interface. For this, I want to convert the java program into a java servlet. I am working in Net Beans.
Following is the structure of my Java program :
public class ABC
{
//code
public ABC() //constructor
{
//code
}
public static void main(String[] args)
{
//code
}
}
I want to convert this into a servlet. Following is the structure of a default servlet in Net Beans.
public class Demo extends Httpservlet
{
/*----
----
----
----*/
public void processRequest(HttpServletRequest request, Httpservlet response)
throws ServletException,IOException
{
/*code*/
}
/*HttpServlet methods - doGet(), doSet() etc.*/
}
Is there any alternative for the main function in the servlet? Which method is executed first when the sevlet starts running? Can I run the Java Program on a button click on a HTML page so that I can eliminate the use of servlet?
use get or post method in servlet depend on your action. There are doGet , doPost and so many HTTP methods you need to determine in which you write code
To use your query processor on the web you will have to build a Java Web Application.
Try the tutorial below and then call your ABC class from a Servlet.
Introduction to Developing Web Applications
Create a Dynamic web project, add new servlet usee doGet method or doPost method refer this link for the same.
servlet example
Hope this helps.
Please have in mind that the purpose of use is different in those two cases. While the main method of a class is invoked when you compile and run it as part of an application (run on a machine), the doGet and doPost methods are invoked in a servlet after a GET/POST request is made by client side to the server side, on which the Servlet lives.
On the first case, usually everything occurs on a specified machine, following the logic "do something, then done", and on the second case, you have a Request/Response Model between Clients and a Server (following the logic "do something when asked, then wait for being asked again"). You need to have a Server (e.g. Tomcat) set up to use the servlets.

Java Servlet and Jquery

Im currently making a Java Servlet that can respond to jquery calls and send back data for my web page to use. But this is only a response using the doGet method.
Is there a way to have multiple methods in a Servlet and call them each with JQuery?
i.e. have a method called Hello and it returns a String "Hello" and another method called Bye and it returns a String "Bye". Is there a way using Jquery or some other technology to do this kind of thing?
Im quite new to servlets so Im still not sure what they are fully capable of. So is the doGet the only method to 'get in' and I just branch responses from there?
With Servlet you can either call the service method, so may be for your scenario you could pass the parameter to decide which method to invoke from doGet()
also you could identify if request is coming from AJAX using header check
There are other technologies available which will allow you directly invoke method See JSF, DWR
See
How to invoke a method with Openfaces/JSF without rendering page?
How to call a java method from jsp by clicking a menu in html page?
Personally I use reflection in my controllers(servlets) which basically let me achieve this.
If I have a servlet called UserController
The main url to call the servlet will be /user.
Knowing this, I always pass my first parameter as ?action=add
Then in my servlet I have a method called add or actionAdd. Whichever you prefer.
Then I use the following code;
String str = String str = request.getParameter("action").toLowerCase();
Method method = getClass().getMethod(str, HttpServletRequest.class, HttpServletResponse.class);
method.invoke(this, request, response);
Explanation:
str will have the action parameters value, add in this case.
Method method will be a reference to a method with the given name(str) and its expected parameter types.
I then invoke the method, passing the context, request and response.
The add method would look something like this;
public void add(HttpServletRequest request,HttpServletResponse response) throws ServletException, IOException {
//do add stuff
String url = "/user/index.jsp";
RequestDispatcher dispatcher = context.getRequestDispatcher(url);
request.setAttribute("User", user);
dispatcher.forward(request, response);
}
I don't know about only passing back a string. But this should get you a basic idea.
Do note that reflection can cost you, altohugh it shouldnt really affect you much like this. And it is error prone as method names/signatures need to match perfectly.
So from jquery you would do an ajax request to the url:
localhost/projectname/user/add (if you use urlrewrite)
or
localhost/projectname/user?action=add (if you dont)
Servlet Container supports Custom Http methods since Servlet 3.0. For Ex,
public void doHello(HttpServletRequest req, HttpServletResponse res) {
//implement your custom method
}
The above method in Servlet can be invoked using hello http method.
But i am not sure if jquery has the support to invoke custom HTTP methods.
If it does not have, then the only option you have.
Invoke Servlet using GET and action parameter.
Read the action parameter and invoke the method using reflection.

Fake a GWT Synchronous RPC call

First of all, I know that doing a synchronous call is "wrong", and know that "is not possible".
But, in a situation a lot complex (i dont know how to explain), i need to wait the response from server, I'am using the GWT-Platform command implementation for the GWT RPC calls.
I was looking for some kind of "hack" for doing this.
Thanks in advance.
Usually, by handling stuff in the onSuccess() function of your RPC request, you'll automatically "wait the response from server". So I assume you want to block all the code currently running? Since JavaScript is single-threaded that won't be easy, there is no sleep function that just halts the program.
But it might be that a hack using a timer does what you want:
Timer checkRPCResponse = new Timer() {
#Override
public void run() {
if (!serverResponseReceived) {
this.schedule(100);
} else {
proceedWithProgram();
}
}
};
checkRPCResponse.schedule(100);
I haven't tried out if the this.schedule(100) works in the above example, but you get the idea, which is a check if the server has responded every 100 ms. Of course you have to set serverResponseReceived = true yourself in the onSuccess() function. Call the timer right after the RPC.
There is a solution but it is not easy (e.g. you cannot flip a single parameter to make it work). GWT is using normal JS XMLHttpRequest under the hood. In GWT there is an overlay type for it called com.google.gwt.xhr.client.XMLHttpRequest. This class is used to send requests to the server over HTTP. Each JS XMLHttpRequest is first initialized by calling method open. This method has few parameters, but the third parameter specifies if the request should be asynchronous. If you change it to false, request will be synchronous.
But GWT-RPC doesn't use this class directly, it using it via RpcRequestBuilder, and this class is not using XMLHttpRequest directly as well, it is using RequestBuilder.
So what you'll need to do is to create customized version of RpcRequestBuilder and RequestBuilder (which will use XMLHttpRequest initialized to be synchronous).
The you can set RPCRequest builder to your GWT-RPC service instance, by casting it to the ServiceDefTarget.
Do you still want to have synchronous GWT-RPC requests?
GWT calls XMLHttpRequest.open() whith true as its third parameter which means the call will be asynchronous. I solved a similar need for testing purposes just forcing this third parameter to be always false:
private static native void fakeXMLHttpRequestOpen() /*-{
var proxied = $wnd.XMLHttpRequest.prototype.open;
(function() {
$wnd.XMLHttpRequest.prototype.open =
function() {
arguments[2] = false;
return proxied.apply(this, [].slice.call(arguments));
};
})();
}-*/;
After invoking fakeXMLHttpRequestOpen(), any further use of XMLHttpRequest will act synchronously. For instance:
remoteSvc.getResult(new AsyncCallback<String>() {
#Override
public void onSuccess(String result) {
GWT.log("Service called!");
}
#Override
public void onFailure(Throwable caught) {
GWT.log("Service failed...");
}
}
GWT.log("Last message");
will allways render:
Service called!
Last message
See https://developer.mozilla.org/en-US/docs/Web/API/XMLHttpRequest/open for XMLHttpRequest.open() specification.

Categories

Resources