如何使用 VaadinServlet 为图像设置 RequestHandler
How to setup a RequestHandler for images with VaadinServlet
我想要一个 RequestHandler
能够在 myDomain/images/id8938748.jpg
处动态创建图像,同时通过标准 VaadinServlet
处理所有其他流量。要做到这一点,我明白我需要通过扩展将 RequestHandler
放在 VaadinServlet
中作为 explained here,例如:
public class MyCustomServlet extends VaadinServlet
{
@Override
protected void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException
{
getService().addSessionInitListener(new SessionInitListener()
{
@Override
public void sessionInit(SessionInitEvent event) throws ServiceException
{
event.getSession().addRequestHandler(myCustomRequestHandlerForImages);
}
});
}
}
我的问题是如何注册新的MyCustomServlet
?我在 web.xml
中查看过这样做,但我似乎无法做到正确。
我的RequestHandler
就是:
@Override
public boolean handleRequest(VaadinSession session, VaadinRequest request, VaadinResponse response) throws IOException
{
System.out.println("Test it's being called");
}
对于 web.xml
我有:
<servlet>
<servlet-name>MyCustomVaadinServlet</servlet-name>
<servlet-class>
com.test.MyCustomVaadinServlet
</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>MyCustomVaadinServlet</servlet-name>
<url-pattern>/images/*</url-pattern>
</servlet-mapping>
然后我在 UI
代码中定义了另一个 Servlet
并带有注释:
public class MyUI extends UI
{
@WebServlet(value = "/*", asyncSupported = true)
@VaadinServletConfiguration(productionMode = false, ui = MyUI.class, widgetset = "com.MyWidgetSet")
public static class Servlet extends VaadinServlet
{
}
...
}
当我调用域本身时,它一切都按预期工作并且我的 Vaadin 应用程序工作。但是当我调用 domain/images 或 domain/images/randomText 时,我得到一个空白页面并且 System.out.println
语句没有输出。基本上 RequestHandler
没有被调用。
我也尝试过映射到 /images/*
和 /app/*
之类的方法,但这没有任何区别...
我认为这不是正确的解决方案,我唯一的解决方案是创建另一个 UI
class 这样:
public class MyImagesUI extends UI
{
@WebServlet(value = "/images/*", asyncSupported = true)
@VaadinServletConfiguration(productionMode = false, ui = MyImagesUI.class, widgetset = "com.MyWidgetset")
public static class Servlet extends VaadinServlet
{
}
@Override
protected void init(VaadinRequest request)
{
VaadinSession.getCurrent().addRequestHandler(new RequestHandler()
{
@Override
public boolean handleRequest(VaadinSession session, VaadinRequest request, VaadinResponse response) throws IOException
{
System.out.println("Test output");
}
});
}
}
这段代码确实有效,并向控制台显示了输出。从那里我可以 response.setContentType("...")
并按照我的需要做,它也能正常工作。
现在我的理解是这不是 "proper way",正确的方法是通过 Servlet
,但与此同时这确实很有效。
如果您在 Vaadin UI 中显示这些图像,例如使用 Image
component, you could use a Resource
。有几种可用的资源实现:
ThemeResource
:将您的文件(例如图像)添加到您的主题中,并使用它来引用图像。
ÈxternalResource
: URL. 上的文件
ClassResource
:类路径上的文件,Vaadin servlet 将文件提供给浏览器。
FileResource
:服务器文件系统上的一个文件。 Vaadin servlet 将文件提供给浏览器。
StreamResource
:从 InputStream
生成文件。 Vaadin servlet 将文件提供给浏览器。
Image image = new Image();
image.setSource(new ThemeResource("path/is/relative/to/the/theme/folder.png"));
一个有效的替代方法是创建一个常规的 servlet 来生成和提供文件。然后您不能再将 Vaadin Servlet 映射到上下文根。然后您可以使用 ExternalResource 来引用您的 Vaadin 代码中的文件:
Image image = new Image();
image.setSource(new ExternalResource("/images/id8938748.jpg"));
您的 servlet 映射如下所示:
<servlet-mapping>
<servlet-name>MyImageServlet</servlet-name>
<url-pattern>/images/*</url-pattern>
</servlet-mapping>
<servlet-mapping>
<servlet-name>MyVaadinServlet</servlet-name>
<url-pattern>/ui/*</url-pattern>
</servlet-mapping>
<servlet-mapping>
<servlet-name>MyVaadinServlet</servlet-name>
<url-pattern>/VAADIN/*</url-pattern>
</servlet-mapping>
我想要一个 RequestHandler
能够在 myDomain/images/id8938748.jpg
处动态创建图像,同时通过标准 VaadinServlet
处理所有其他流量。要做到这一点,我明白我需要通过扩展将 RequestHandler
放在 VaadinServlet
中作为 explained here,例如:
public class MyCustomServlet extends VaadinServlet
{
@Override
protected void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException
{
getService().addSessionInitListener(new SessionInitListener()
{
@Override
public void sessionInit(SessionInitEvent event) throws ServiceException
{
event.getSession().addRequestHandler(myCustomRequestHandlerForImages);
}
});
}
}
我的问题是如何注册新的MyCustomServlet
?我在 web.xml
中查看过这样做,但我似乎无法做到正确。
我的RequestHandler
就是:
@Override
public boolean handleRequest(VaadinSession session, VaadinRequest request, VaadinResponse response) throws IOException
{
System.out.println("Test it's being called");
}
对于 web.xml
我有:
<servlet>
<servlet-name>MyCustomVaadinServlet</servlet-name>
<servlet-class>
com.test.MyCustomVaadinServlet
</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>MyCustomVaadinServlet</servlet-name>
<url-pattern>/images/*</url-pattern>
</servlet-mapping>
然后我在 UI
代码中定义了另一个 Servlet
并带有注释:
public class MyUI extends UI
{
@WebServlet(value = "/*", asyncSupported = true)
@VaadinServletConfiguration(productionMode = false, ui = MyUI.class, widgetset = "com.MyWidgetSet")
public static class Servlet extends VaadinServlet
{
}
...
}
当我调用域本身时,它一切都按预期工作并且我的 Vaadin 应用程序工作。但是当我调用 domain/images 或 domain/images/randomText 时,我得到一个空白页面并且 System.out.println
语句没有输出。基本上 RequestHandler
没有被调用。
我也尝试过映射到 /images/*
和 /app/*
之类的方法,但这没有任何区别...
我认为这不是正确的解决方案,我唯一的解决方案是创建另一个 UI
class 这样:
public class MyImagesUI extends UI
{
@WebServlet(value = "/images/*", asyncSupported = true)
@VaadinServletConfiguration(productionMode = false, ui = MyImagesUI.class, widgetset = "com.MyWidgetset")
public static class Servlet extends VaadinServlet
{
}
@Override
protected void init(VaadinRequest request)
{
VaadinSession.getCurrent().addRequestHandler(new RequestHandler()
{
@Override
public boolean handleRequest(VaadinSession session, VaadinRequest request, VaadinResponse response) throws IOException
{
System.out.println("Test output");
}
});
}
}
这段代码确实有效,并向控制台显示了输出。从那里我可以 response.setContentType("...")
并按照我的需要做,它也能正常工作。
现在我的理解是这不是 "proper way",正确的方法是通过 Servlet
,但与此同时这确实很有效。
如果您在 Vaadin UI 中显示这些图像,例如使用 Image
component, you could use a Resource
。有几种可用的资源实现:
ThemeResource
:将您的文件(例如图像)添加到您的主题中,并使用它来引用图像。ÈxternalResource
: URL. 上的文件
ClassResource
:类路径上的文件,Vaadin servlet 将文件提供给浏览器。FileResource
:服务器文件系统上的一个文件。 Vaadin servlet 将文件提供给浏览器。StreamResource
:从InputStream
生成文件。 Vaadin servlet 将文件提供给浏览器。Image image = new Image(); image.setSource(new ThemeResource("path/is/relative/to/the/theme/folder.png"));
一个有效的替代方法是创建一个常规的 servlet 来生成和提供文件。然后您不能再将 Vaadin Servlet 映射到上下文根。然后您可以使用 ExternalResource 来引用您的 Vaadin 代码中的文件:
Image image = new Image();
image.setSource(new ExternalResource("/images/id8938748.jpg"));
您的 servlet 映射如下所示:
<servlet-mapping>
<servlet-name>MyImageServlet</servlet-name>
<url-pattern>/images/*</url-pattern>
</servlet-mapping>
<servlet-mapping>
<servlet-name>MyVaadinServlet</servlet-name>
<url-pattern>/ui/*</url-pattern>
</servlet-mapping>
<servlet-mapping>
<servlet-name>MyVaadinServlet</servlet-name>
<url-pattern>/VAADIN/*</url-pattern>
</servlet-mapping>