Dynamic Content
To generate content dynamically based on data provided by the current application state, there are two options:
-
You can use a
StreamResource
, which handles URLs automatically. -
You can build a custom URL using
String
type parameters. In this case, you need one more servlet, which handles the URL.
The first option is preferable, since it doesn’t require an additional servlet and allows you to use data of 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 generates the URL transparently for you and registers 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 is automatically 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 also becomes the filename, if the user chooses to download the resource.
And here is an example of 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));
}
DF78C6F1-4DFC-4F65-A0D4-29CCB2CFEDD5