如何使用VaadinServlet为图像设置RequestHandler

时间:2015-07-18 04:02:16

标签: javascript java java-ee vaadin vaadin7

我希望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>

然后我在Servlet代码中使用注释定义了另一个UI

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应用程序正常工作。但是当我调用域/图像或域/图像/ randomText时,我得到一个空页面并且不输出System.out.println语句。基本上不会调用RequestHandler

我还尝试了映射到/images/*/app/*之类的内容,但这没有任何区别......

2 个答案:

答案 0 :(得分:3)

如果您使用Image组件在Vaadin用户界面中显示这些图片,则可以使用Resource。有几种可用的资源实现:

  • ThemeResource:将您的文件(例如图片)添加到您的主题中,然后使用它来引用图片。
  • ÈxternalResource:网址上的文件。
  • 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>

答案 1 :(得分:0)

我认为唯一的解决方案就是创建另一个UI类,以便:

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("...")并按照我的需要做,并且也可以。

现在我的理解是,这不是“正确的方法”,正确的方法是通过Servlet,但同时这确实很有效。