嵌入Vaadin + Springboot应用到Vaadin UI使用Emdedded UI插件

问题描述:

我目前正在使用springboot和Vaadin 8微服务,我想用Embedded UI 2.0附加的Vaadin。
我第一次尝试中嵌入简单Springboot + Vaadin到宿主Vaadin应用如图中 example
下面是宿主应用程序的结果代码:嵌入Vaadin + Springboot应用到Vaadin UI使用Emdedded UI插件

import ... 
import org.vaadin.embedded.VaadinUIComponent; 


@Theme(ValoTheme.THEME_NAME) 
public class HostUI extends UI { 

@Override 
protected void init(VaadinRequest vaadinRequest) { 
    /*My Spring boot application */  
    VaadinUIComponent ui1 = new VaadinUIComponent("http://localhost:8081/app2/"); 
    ui1.setSizeFull(); 
    /* A simple vaadin application*/ 
    VaadinUIComponent ui2 = new VaadinUIComponent("http://localhost:9020"); 

    HorizontalSplitPanel split = new HorizontalSplitPanel(ui1, ui2); 
    split.setSizeFull(); 
    setContent(split); 
} 

,但我一直有与VAADIN/*资源负载的问题:

{"timestamp":1501683162735,"status":404,"error":"Not Found","message":"No message available","path":" 
/app2/widgetsets/ws84167e472e91ff0ea8255f8f1b189aa0/ws84167e472e91ff0ea8255f8f1b189aa0.nocache.js"} 

其中/app2/是通向我的应用程序。

我不知道该路径的资源如何解决,但我知道Vaadin目录应该是/app2/VAADIN/*以来的视觉元件和其他vaadin编译资源工作得很好,当我打开可用应用程序直接从我的浏览器。
下面是一些附加信息:

  • Vaadin版本:8.0.5
  • 嵌入式UI插件版本:2.0
  • 我用ValoTheme所有3个应用程序(主机和嵌入)
  • vaadin.widgetset.mode设置为fetch模式
  • 我确保为应用程序启用了CORS。

我搜索了很长时间来解决这个问题,但没有找到足够的来源为这种特殊情况,我也是一个初学者在春季和Vaadin,所以我绝对可以使用一些帮助。

+0

没有检查的附加来源,但我有一种预感它的紧耦合的引导,很可能调度的servlet和servlet的Vaadin维护您的应用程序的要求。如果您可以提供[sscce](http://sscce.org)来轻松地重现您的问题,它可能会帮助您获得一些答案。 – Morfic

+0

这是一个[链接](https://github.com/zelha/45465131-sscce.git)到一个存储库,我重现了错误,如果没关系。 –

Morfic的很好的解释!谢谢。是的,附加组件存在问题。在2.1中修复。请参阅更多信息以https://vaadin.com/forum#!/thread/16448312

TL; DR;版本

这似乎是一个插件中的错误,并且有一个类似的issue open on their tracker,不知道它是你还是其他人。但为什么你首先需要使用它?你想要实现的是什么,这是常规的Vaadin应用程序无法完成的,你需要嵌入多个UI?


详细版本

所以我做了一些挖掘和你的观察是正确的,/VAADIN/从路径丢失。在春季启动应用程序中,可能还会有其他由vaadinServlet处理的失败请求,例如心跳和uidl。

单机应用程序请求:

stand alone app request

嵌入式应用程序请求:

embedded app request

随着一点点的模式调试,似乎附加确实使用不正确的路径: incorrect path

最后追溯到BAC k到./VAADIN的错误正则表达式替换为http://localhost:9030/而不是正确的http://localhost:9030/VAADIN

在我看来,就像它在附加的错误,但可能只有开发可以确认或解释为什么它正在这样做。

regex replacement

这样的工作,我们周围可以使用弹簧控制器重定向请求到正确的URL,但即使这样有它的局限性。它在第一页刷新时打破,因为通常增加的v-uiId仍为0.

import org.springframework.stereotype.Controller; 
import org.springframework.web.bind.annotation.RequestMapping; 
import org.springframework.web.servlet.HandlerMapping; 

import javax.servlet.http.HttpServletRequest; 

@Controller 
public class VaadinRedirectController { 
    private static final String INCOMPLETE_WIDGETSET_PATH = "/widgetsets/**"; 
    private static final String INCOMPLETE_THEME_PATH = "/themes/**"; 
    private static final String INCOMPLETE_UIDL_PATH = "/UIDL/**"; 
    private static final String INCOMPLETE_HEARTBEAT_PATH = "/HEARTBEAT/**"; 

    @RequestMapping(value = {INCOMPLETE_WIDGETSET_PATH, INCOMPLETE_THEME_PATH,}) 
    public String redirectWidgetsetAndThemeRequests(HttpServletRequest request) { 
     return createRedirectPath(request, "VAADIN"); 
    } 

    @RequestMapping(value = {INCOMPLETE_UIDL_PATH, INCOMPLETE_HEARTBEAT_PATH}) 
    public String redirectUidlAndHeartbeatRequests(HttpServletRequest request) { 
     return createRedirectPath(request, "vaadinServlet"); 
    } 

    private String createRedirectPath(HttpServletRequest request, String prefix) { 
     String path = "redirect:/" + prefix + getPath(request); 
     if (request.getQueryString() != null && !request.getQueryString().isEmpty()) { 
      path += "?" + request.getQueryString(); 
     } 
     return path; 
    } 

    private Object getPath(HttpServletRequest request) { 
     return request.getAttribute(HandlerMapping.PATH_WITHIN_HANDLER_MAPPING_ATTRIBUTE); 
    } 
} 
+0

感谢您的回答。 我需要使用附加组件作为UI组合问题的解决方案,因为我必须构建一些UI屏幕或页面来显示我的多个服务的UI(以便每个服务都可以拥有它自己的独立UI,并且可以访问没有“主机”应用程序)。 关于你的解决方案,我试着实现它,并做了一些测试: 控制器按照预期重定向所有请求,比如'localhost:8080/widgetsets/**';但不是'localhost:8080widgetsets/**',这是主机应用程序产生的URL。我不知道是否有可能的解决方案。 –

+0

@ Zineb.elh是的,忘了这一点,在你的主机应用程序中添加一个'/'到启动应用程序url :-)。但请记住,它仍然在首次刷新时崩溃...还没有找到解决方案。 – Morfic

+0

再次感谢您的帮助。我知道这不是问题的最终解决方案。我正在等待附加开发人员研究它。我试图理解每个请求发送的'v-uiId'的作用,以便解决这个问题。我注意到UI不会相互作用(即,当我点击一个按钮时不会改变)。这与'v-uiId'问题有关吗? –