[Logo] IT Mill Toolkit Forum
  [Search] Search   [Recent Topics] Recent Topics   [Members]  Member Listing   [Groups] Back to home page 
[Register] Register / 
[Login] Login 
Problems using handleURI  XML
Forum Index -> General Help Go to Page: 1, 2 Next 
Author Message
QuentinAstegiano



Joined: 16/01/2008 15:10:43
Messages: 38
Location: Paris, France
Offline

Hi

First of all things, thank you very much for all your work with ITMill - a truly superb framework, alas not known enough.

Anyway.
I have some troubles using handleURI.

In my application, I have a GWT widget embedding a map, based on OpenLayers. When I click on my map, for example to select a feature on a layer, I've got a Javascript function sending and receiving informations from a distant server.
I want to transmit those informations (contained in a javascript variable) to my server.

After reading the doc, I tried to add an URIHandler to my main window.
My Javascript function make an Ajax call to my application.

On my handling function, I am able to retrieve my JS variable without any problem.
Trouble is... I can do nothing with it.
I would like to display that information processed by my server in a Label that I would add in my main window.

My functions are called, I can trace them using the standard output... but nothing happen in my application

What am I doing wrong ?

Excerpt from my source code:
Code:
public class MainApplication extends Application {
     private Window main;
 
     public void init() {
         main = new Window("OpenLayer Integration Test");
         setMainWindow(main);
         final MainPanel mainPanel = new MainPanel();
 [...]
         main.addURIHandler(this);
 
         main.addComponent(mainPanel);
     }
 
     public DownloadStream handleURI(URL url, String context) {
         main.showNotification("Handle URI: " + context); // I have a notification on the first call, when the window is initialized, but nothing after
         System.out.println("Context: " + context); // When my JS function fire, this do write a trace in my default log output
 [...]
     }
 }


I am using ITMill Toolkit 5, the last public release as far as I can tell.

Thank you very much for your help

Quentin.
QuentinAstegiano



Joined: 16/01/2008 15:10:43
Messages: 38
Location: Paris, France
Offline

After watching my HTTP trafic, when I send my request using an Ajax POST, I get an HTML response.
I do not know why, nor if it can help...

Received response:Code:
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
 
 <html xmlns="http://www.w3.org/1999/xhtml" style="width:100%;height:100%;border:0;margin:0;">
 <head>
 <title>IT Mill Toolkit 5</title>
 <script type="text/javascript">
 	var itmill = {
 		appUri:'/OpenLayerITMill/openlayer', pathInfo: '/showfeature', themeUri: null
 };
 </script>
 <script language='javascript' src='/OpenLayerITMill/ITMILL/widgetsets/com.masa.openlayers.itmill.widgets.map.MapWidgetSet/com.masa.openlayers.itmill.widgets.map.MapWidgetSet.nocache.js'></script>
 </head>
 <body class="i-generated-body">
 	<iframe id="__gwt_historyFrame" style="width:0;height:0;border:0;overflow:hidden"></iframe>
 	<div id="itmill-ajax-window" style="position: absolute;top:0;left:0;width:100%;height:100%;border:0;margin:0"></div>	
 </body>
 </html>
Maybe it is because the JS function firing the call is located in my GWT widget embedding my map ?

I really do not have any clue of what is happening

Quentin.
Marko Grönroos



Joined: 23/07/2007 15:34:05
Messages: 100
Offline

QuentinAstegiano wrote:
Hi

First of all things, thank you very much for all your work with ITMill - a truly superb framework, alas not known enough. 
Thanks. We try to do our best to make it known better. Feel free to recommend it to others.

I want to transmit those informations (contained in a javascript variable) to my server. 
Ok. One way to do that is to create a new client-side widget to do client-server communications, but I suppose sending it directly from your JavaScript and using the URIHandler at server-side, as you have tried to do, should also work. Making a custom GWT widget is perhaps a bit heavy task compared to the alternative way. I'm not exactly sure what obstacles you might have there though.

After watching my HTTP trafic, when I send my request using an Ajax POST, I get an HTML response.  
It looks like the response contains the usual initial page. My first quess is the way how the server side tracks the sessions using cookies. The direct JavaScript post might not include all the information needed for tracking the session. I'll have to check how that works.
Marko Grönroos



Joined: 23/07/2007 15:34:05
Messages: 100
Offline

Ok, there's one huge problem in passing the variable with a custom Ajax call that bypasses the Toolkit's Ajax communications. You might be able to pass the variable value to the server using handleURI, but that doesn't really do anything, because the server response would not update the client-side so you could not have any UI feedback from the call.

So, I recommend doing the client-server communication in the standard way by implementing a GWT widget and a server-side component to pass the variable to the server. The ColorPicker demo provides a really simple example of passing one variable to the server. It should be well documented in the manual. Since you already have a GWT widget, you can probably do the communications easiest by inheriting it, as is done in ColorPicker.

QuentinAstegiano



Joined: 16/01/2008 15:10:43
Messages: 38
Location: Paris, France
Offline

Thank you for your response

Before reading it, I did a few more tests, and weird things happened.

The only thing I added was... A button. Doing nothing related to my functions.

When I fire my JS Ajax call, the "server side" function are correctly called; I can see trace in my log. But nothing happen "client side", even though, well, it should and it say it does.
But when I click on my not-related-button, the missing events happens all at once client side ?!

It look like everything is ok, and the only problem is that the client state is not refreshed after my call. Can I force the client to "refresh" himself ?
I tried to add call to "main.requestRefresh()", but it changed nothing (and I'm not really sure of what this function is doing ^^).
Considering your last response, and as you said, the server response does not update the client side, I guess the answer is "no", but, eh, I prefer be sure

New version of my code:
Code:
 public class MainApplication extends Application {
 
     private Window main;
 
     public void init() {
         main = new Window("OpenLayer Integration Test");
         main.addURIHandler(this);
         setMainWindow(main);
         final MainPanel mainPanel = new MainPanel();
 
         final Button button = new Button("Any news ?");
         final Label label = new Label();
         button.addListener(new Button.ClickListener() {
 
             public void buttonClick(Button.ClickEvent arg0) {
                 label.setCaption("There is news"); // Right after this event happen, my handleURI notification happen client side !
             }
         });
 
         main.addComponent(mainPanel);
         main.addComponent(label);
         main.addComponent(button);
     }
 
     public DownloadStream handleURI(URL url, String context) {
         main.showNotification("Handle URI: " + context);
 [...]
     }
 }


I will try to use the GWT widget, but it may be a bit tricky in my case.
The JS function making the Ajax call is a callback function, called in response to an event depending on another server... Integrating that with GWT may be, err, quite though ^^

Thank you again for your time

Quentin.
Marko Grönroos



Joined: 23/07/2007 15:34:05
Messages: 100
Offline

QuentinAstegiano wrote:
When I fire my JS Ajax call, the "server side" function are correctly called; I can see trace in my log. But nothing happen "client side", even though, well, it should and it say it does.
But when I click on my not-related-button, the missing events happens all at once client side ?! 

That is exactly what I expect would happen. All UI updates to the client-side are transmitted in the response to an Ajax request made by the client-side engine of the Toolkit. If you make an Ajax call from your own JavaScript and handle it with handleURI(), you can change the server state, but the UI is updated only after you have a regular Ajax request by the client-side engine.

If you are using Firebug or something similar, you can see what happens normally. When you click a button, the client-side engine makes an Ajax request to the server with the button event. The response contains all the UI changes caused by the event. To have effect, the client-side must handle that response. That's really what the purpose of the client-side engine is.

It look like everything is ok, and the only problem is that the client state is not refreshed after my call. Can I force the client to "refresh" himself ? 

Well, yes, by making the client-side engine make an empty request to the server, but that would be making two server requests for one event, which does not really make sense.

I tried to add call to "main.requestRefresh()", but it changed nothing (and I'm not really sure of what this function is doing ^^). 

requestRefresh()? Normally, when you click a button managed by the client-side engine, it uses the ApplicationConnection object to communicate with the server. Clicking on the button queues a status variable change to the object and sendPendingVariableChanges() sends the queued variables in a XmlHttpRequest. ...and gets any UI changes in the response.

Code:
     public DownloadStream handleURI(URL url, String context) {
         main.showNotification("Handle URI: " + context);
 [...]
     }
 }
 

Yes, that can not work. The notification would not be shown in the browser, because it is not communicated to the client-side in the custom Ajax request that you make.

I will try to use the GWT widget, but it may be a bit tricky in my case. The JS function making the Ajax call is a callback function, called in response to an event depending on another server... Integrating that with GWT may be, err, quite though ^^ 

It should be possible to integrate IT Mill Toolkit with any JavaScript code in the client-side. I'll have to look how to do that. But in any case, the proper way to do it is through the client-side framework.

Making a custom GWT widget with custom JavaScript is documented in http://code.google.com/webtoolkit/documentation/com.google.gwt.doc.DeveloperGuide.UserInterface.html#CreatingCustomWidgets , though the documentation there is not very good.
Marko Grönroos



Joined: 23/07/2007 15:34:05
Messages: 100
Offline

QuentinAstegiano wrote:
When I fire my JS Ajax call, the "server side" function are correctly called; I can see trace in my log. But nothing happen "client side", even though, well, it should and it say it does.
But when I click on my not-related-button, the missing events happens all at once client side ?! 

Well ok, if you want to go with the easy but dirty way, you could have the client-side engine of IT Mill Toolkit poll the server periodically. While the UI changes are not updated in the handleURI() call, they will be when you poll the server. That should make your program work right away.

Currently the easiest way to do polling is use ProgressIndicator. You can make the component invisible with a single CSS line. See Forum article http://forum.itmill.com/posts/list/345.page for info for using the ProgressIndicator. I wrote about it in the Manual as well, but it's not in the web site yet.

Anyhow, I'll have to examine the issue further at some point and write something about integration with JavaScript in the Manual. You need to make a custom GWT widget that provides an interface to JavaScript. I think it's done as a JNI interface. It's also possible that we could write a generic API that a JavaScript program could use.
Marc Englund


[Avatar]

Joined: 07/03/2007 15:18:36
Messages: 59
Location: Turku, Finland
Offline

The problem is as Marko describes it:

1.1. custom javascript sends update to server
1.2. server reacts, updates (serverside) ui
1.3. but the updates are not drawn on the client, since the custom javascript does not know how to do that
2.1. pressing the button causes the (itmill/gwt) client to send a button click event to the server
2.2. the server reacts and updates the ui
2.3. the server returns UI changes, including the ones caused earlier by the custom javascript call to the (itmill/gwt) client, which updates the clientside ui

There are several ways to tackle this problem, including Markos ProgressIndicator suggestion. Making a new component would be the most robust and "proper" way.

We're definitely going to improve js<->gwt<->toolkit integration, making it easier to communicate with 'custom' javascript (i.e. javascript API).
An easy improvement that would allow you to get this 'simple' case working would be to publish some sort of refreshFromServer() -method that you could call from javascript.

Best regards,
Marc
[WWW]
Marc Englund


[Avatar]

Joined: 07/03/2007 15:18:36
Messages: 59
Location: Turku, Finland
Offline

Quentin,

I implemented a forceSync() function that should solve your problem; the client exposes this function to javascript, so you can call it to synchronize the client with the server.

In practice:
after your JS Ajax call returns, call itmill.forceSync()
Code:
itmill.forceSync();


This function should be available in the next nightly build, and the FeatureBrowser will contain a minimal example as well.

Best regards,
Marc
[WWW]
QuentinAstegiano



Joined: 16/01/2008 15:10:43
Messages: 38
Location: Paris, France
Offline

Wow !
You rocks

Thank you very much for the time you put into helping me.

I'm currently making test using a GWT widget, but this is, well... quite complicated.

I'll test your solution as soon as possible.

Thank you again !

Quentin.
QuentinAstegiano



Joined: 16/01/2008 15:10:43
Messages: 38
Location: Paris, France
Offline

Err...

You're going to hate me

I've downloaded the nightly build (itmill-toolkit-5.0.0_trunk_20080118.jar, right ?). But I've got a bug with it

There seems to be a problem with the communications between the client & the server.
After having some bugs, I've set up a simple test:

Code:
public class MainApplication extends Application {
 
     private Window main;
 
     public void init() {
         main = new Window("OpenLayer Integration Test");
         setMainWindow(main);
         
         Button button = new Button("test");
         button.addListener( new Button.ClickListener() {
 
             public void buttonClick(Button.ClickEvent arg0) {
                 main.showNotification("Test");
                 System.out.println("Test");
             }
         });
         main.addComponent(button);
         
     }
 }
When I click the button, I've got the following exception:
Code:
java.lang.ArrayIndexOutOfBoundsException: 1
         at com.itmill.toolkit.terminal.gwt.server.CommunicationManager.handleVariables(CommunicationManager.java:487)
         at com.itmill.toolkit.terminal.gwt.server.CommunicationManager.handleUidlRequest(CommunicationManager.java:274)
         at com.itmill.toolkit.terminal.gwt.server.ApplicationServlet.service(ApplicationServlet.java:394)
         at javax.servlet.http.HttpServlet.service(HttpServlet.java:803)
         at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:290)
         at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
         at org.netbeans.modules.web.monitor.server.MonitorFilter.doFilter(MonitorFilter.java:196)
         at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:235)
         at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
         at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:233)
         at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:175)
         at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:128)
         at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:102)
         at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:109)
         at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:263)
         at org.apache.coyote.http11.Http11Processor.process(Http11Processor.java:844)
         at org.apache.coyote.http11.Http11Protocol$Http11ConnectionHandler.process(Http11Protocol.java:584)
         at org.apache.tomcat.util.net.JIoEndpoint$Worker.run(JIoEndpoint.java:447)
         at java.lang.Thread.run(Thread.java:619)
 


I've cleaned my installations and rebuilt default & personal widgets. No problem occurs during the build, the app launch without problems, my panels & widgets appears. The problem only occurs when the client send an event to the server, it seems.

Am I doing something wrong here ?

Sorry to bother you like that, and thank you for your help

Quentin.

EDIT Some more details:
- From Firebug, request POST parameters:
Code:
changes=PID28_state_btrue


- Headers:
Code:
Response Headers
 
 Server	Apache-Coyote/1.1
 Content-Length	1884
 Date	Mon, 21 Jan 2008 10:22:14 GMT
 
 Request Headers
 
 Host	localhost:8084
 User-Agent	Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.8.1.11) Gecko/20071231 Firefox/2.0.0.11 Flock/1.0.5
 Accept	text/xml,application/xml,application/xhtml+xml,text/html;q=0.9,text/plain;q=0.8,image/png,*/*;q=0.5
 Accept-Language	en-us,en;q=0.7,fr;q=0.3
 Accept-Encoding	gzip,deflate
 Accept-Charset	ISO-8859-1,utf-8;q=0.7,*;q=0.7
 Keep-Alive	300
 Connection	keep-alive
 Content-Type	application/x-www-form-urlencoded; charset=utf-8
 Referer	http://localhost:8084/OpenLayerITMill/ITMILL/widgetsets/com.masa.openlayers.itmill.widgets.map.MapWidgetSet/8D8F9B3DE12FDC36DAF65358A95990F6.cache.html
 Content-Length	26
 Cookie	JSESSIONID=5498B0B6F275862EA3D5FF582F23683C
 Pragma	no-cache
 Cache-Control	no-cache
I'm not sure to understand why the response header refer to "com.masa.openlayers.itmill.widgets.map.MapWidgetSet" as this button do not, in any way, refer to this widget...
Marc Englund


[Avatar]

Joined: 07/03/2007 15:18:36
Messages: 59
Location: Turku, Finland
Offline

Hmm...

I could not reproduce this (quickly anyway), but I'm guessing: the application seems to be using your custom WidgetSet ("com.masa.openlayers.itmill.widgets.map.MapWidgetSet") which is probably not compiled after the IT Mill Toolkit update (OR something is cached too well). If my guess is correct, you're using an old client with a new server - try recompiling your "MapWidgetSet" and see if that helps.

(A new version will very seldom cause this kind of problem, but some variable naming changes in the current nightly might actually break communication with an old client in the way you describe.)

And, don't worry, we won't hate you - we know some of these problems are hard to figure out without in-depth knowledge of how the Toolkit works. You're helping to get that knowledge on to this forum

Hope this helps!
//Marc
[WWW]
QuentinAstegiano



Joined: 16/01/2008 15:10:43
Messages: 38
Location: Paris, France
Offline

\o/ It's working

You where totally right.
My widget was not rebuilt with the right library (a reference to the previous jar I stupidly missed in my ant build file), and thus didn't worked.

Now, everything seems to be working smoothly.

Thank you very much for your help

Quentin.
QuentinAstegiano



Joined: 16/01/2008 15:10:43
Messages: 38
Location: Paris, France
Offline

Err...

Ok, I've got something working, and hit a wall two minutes after.

So.
I can retrieve my URL calls, no prob. I'm sync with the client, no prob.
Trouble is... I want to use that request to send parameters to the server - kinda huge parameters, forcing me to use POST request.

But in my handleURI function, the only thing I have is the requested URL, and not the request - and so my POST parameters are kinda lost in space somewhere.

Any thought on an easy way for me to get them ? Using GET is a no-no, as the parameters may be quite a big chunk of data (retrieved from another server, but that is another story ^^).

Quentin.

EDIT: Hmmm ok. After some research to understand what handleURI was REALLY doing, I finally understood that even GET parameters are not accessible at this point.
Is there any way to access the original request object ?
Marko Grönroos



Joined: 23/07/2007 15:34:05
Messages: 100
Offline

QuentinAstegiano wrote:
But in my handleURI function, the only thing I have is the requested URL, and not the request - and so my POST parameters are kinda lost in space somewhere.

Any thought on an easy way for me to get them ? Using GET is a no-no, as the parameters may be quite a big chunk of data (retrieved from another server, but that is another story ^^). 

You can implement a ParameterHandler (http://toolkit.itmill.com/demo/doc/api/com/itmill/toolkit/terminal/ParameterHandler.html) instead of the URI handler. You instantiate the handler and add it to the main window with addParameterHandler().

Notice that the parameter handler is for a window, not the application. See WebContent/WEB-INF/src/com/itmill/toolkit/demo/Parameters.java in the Toolkit installation package.

If you want to use some other URL but the base URL for the application to send the request, you have to handle it a bit differently. There's no combined URIhandler and parameter handler. The URIhandler is, however, always called before the parameter handler, so you could store the URI in the URIhandler and use it in the parameter handler. Another way is to create another Window object that has a particular URL (use setName()). So, if your base URL is http://localhost:8080/myproject/myapp/, and create a new window with setName("foobar"), the window URL should be http://localhost:8080/myproject/myapp/foobar/ .
 
Forum Index -> General Help Go to Page: 1, 2 Next 
Go to:   
Powered by JForum 2.1.7 © JForum Team