Dynamic Content
There are two options to generate content dynamically based on data provided by the current application state:
-
You can use a
StreamResource
which will handle URLs automatically. -
You can build a custom URL including parameters with
String
type parameters. In this case you will need one more servlet which handles the URL.
The first option is preferable since it doesn’t require additional servlet and allows to use data with any type from the application state.
Using custom servlet and request parameters
You can create a custom servlet which handles "image" as a relative URL:
@WebServlet(urlPatterns = "/image", name = "DynamicContentServlet")
public class DynamicContentServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException {
resp.setContentType("image/svg+xml");
String name = req.getParameter("name");
if (name == null) {
name = "";
}
String svg = "<?xml version='1.0' encoding='UTF-8' standalone='no'?>"
+ "<svg xmlns='http://www.w3.org/2000/svg' "
+ "xmlns:xlink='http://www.w3.org/1999/xlink'>"
+ "<rect x='10' y='10' height='100' width='100' "
+ "style=' fill: #90C3D4'/><text x='30' y='30' fill='red'>"
+ name + "</text>" + "</svg>";
resp.getWriter().write(svg);
}
}
The following code should be used in the application (which has its own servlet). It generates the resource URL on the fly based on the current application state. The property value of the input component is used here as a state:
Input name = new Input();
Element image = new Element("object");
image.setAttribute("type", "image/svg+xml");
image.getStyle().set("display", "block");
NativeButton button = new NativeButton("Generate Image");
button.addClickListener(event -> {
String url = "image?name=" + name.getValue();
image.setAttribute("data", url);
});
UI.getCurrent().getElement().appendChild(name.getElement(), image,
button.getElement());
Using StreamResource
Use StreamResource
to generate dynamic content within the same servlet.
In this case the application will generate the URL transparently for you and register an internal handler for this URL.
The code below shows how to implement the same functionality as above using StreamResource
.
Input name = new Input();
Element image = new Element("object");
image.setAttribute("type", "image/svg+xml");
image.getStyle().set("display", "block");
NativeButton button = new NativeButton("Generate Image");
button.addClickListener(event -> {
StreamResource resource = new StreamResource("image.svg",
() -> getImageInputStream(name));
image.setAttribute("data", resource);
});
UI.getCurrent().getElement().appendChild(name.getElement(), image,
button.getElement());
The data
attribute value is set to the StreamResource, which will automatically be converted into a URL. A StreamResource
uses a dynamic data provider to produce the data.
The file name given to a StreamResource
is used as a part of the URL and will also become the filename if the user selects to download the resource.
And here is an example how to create a data provider:
private InputStream getImageInputStream(Input name) {
String value = name.getValue();
if (value == null) {
value = "";
}
String svg = "<?xml version='1.0' encoding='UTF-8' standalone='no'?>"
+ "<svg xmlns='http://www.w3.org/2000/svg' "
+ "xmlns:xlink='http://www.w3.org/1999/xlink'>"
+ "<rect x='10' y='10' height='100' width='100' "
+ "style=' fill: #90C3D4'/><text x='30' y='30' fill='red'>"
+ value + "</text>" + "</svg>";
return new ByteArrayInputStream(svg.getBytes(StandardCharsets.UTF_8));
}
45832A61-422D-4839-9A51-0A6AE1410983