In one of my projects, I use a custom widget which (more or less) retreive a map from the server, and allow the user to interact with it (doing zoom, pans, etc.)
Getting the image is easy: I use an URIHandler and send back a DownloadStream filled with the byte array of my map.
But when I want my user to interact with the map, I am in trouble. I have to pass GET parameters to the servlet, and to be able to process them
before sending back the image.
In other words, I would like to be able to contact my server an URL something like http://server/application/GetMap?cmd=zoom&factor=1.5 , so that I can get the user command, process it, and then send back the zoomed map.
So, what I need server side is either a handler giving me at the same time the relative URI & the parameters Map, or even access to the HttpRequest object itself.
But in fact, the parameter handler is called
before the URI handler (and it is much more logical that way !), as I found out while reading the service() method in the ApplicationServlet class
So I’m able to process my parameters before sending back my image, so I’m happy ^^
Anyway, some way to access the HttpServlet object would be a neat feature, in a future version… It is sometimes usefull to be able to manipulate the low level objects
You can access HttpServletRequest. Add TransactionListener to your Application. transactionData parameter can be casted to javax.servlet.http.HttpServletRequest
Below is an example (possibly for the manual) for using both parameter and URI handlers to create dynamic content.
package com.itmill.toolkit.tests.book;
import java.awt.Color;
public class MyDynamicResource implements URIHandler, ParameterHandler {
String textToDisplay = "- no text given -";
ByteArrayOutputStream imagebuffer = null;
/**
* Handle the URL parameters and store them for the URI handler to use.
*/
public void handleParameters(Map parameters) {
// Get and store the passed HTTP parameter.
if (parameters.containsKey("text"))
textToDisplay = ((String[])parameters.get("text"))[0]
;
}
/**
* Provides the dynamic resource if the URI matches the resource URI. The
* matching URI is "/myresource" under the application URI context.
*
* Returns null if the URI does not match. Otherwise returns a download
* stream that contains the response from the server.
*/
public DownloadStream handleURI(URL context, String relativeUri) {
// Catch the given URI that identifies the resource, otherwise let other
// URI handlers or the Application to handle the response.
if (!relativeUri.startsWith("myresource"))
return null;
// Create an image and draw some background on it.
BufferedImage image = new BufferedImage (200, 200, BufferedImage.TYPE_INT_RGB);
Graphics drawable = image.getGraphics();
drawable.setColor(Color.lightGray);
drawable.fillRect(0,0,200,200);
drawable.setColor(Color.yellow);
drawable.fillOval(25,25,150,150);
drawable.setColor(Color.blue);
drawable.drawRect(0,0,199,199);
// Use the parameter to create dynamic content.
drawable.setColor(Color.black);
drawable.drawString("Text: "+textToDisplay, 75, 100);
try {
// Write the image to a buffer.
imagebuffer = new ByteArrayOutputStream();
ImageIO.write(image, "png", imagebuffer);
// Return a stream from the buffer.
ByteArrayInputStream istream = new ByteArrayInputStream(imagebuffer.toByteArray());
return new DownloadStream (istream,null,null);
} catch (IOException e) {
return null;
}
}
}
When you use the class in an application, you must (obviously) share the same handler object with both handlers:
MyDynamicResource myresource = new MyDynamicResource();
mainWindow.addParameterHandler(myresource);
mainWindow.addURIHandler(myresource);