0

我目前正在使用 springboot 和 Vaadin 8 开发微服务,并且我想为 Vaadin 使用Embedded UI 2.0插件。
我首先尝试将简单的 Springboot + Vaadin 嵌入到主机 Vaadin 应用程序中,如示例所示。
这是主机应用程序的结果代码:

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。

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

4

2 回答 2

0

Morfic的解释很好!谢谢。是的,插件有问题。在 2.1 中修复。请在https://vaadin.com/forum#!/thread/16448312查看更多信息

于 2017-08-04T13:49:13.490 回答
0

TL;博士; 版本

这似乎是插件中的一个错误,并且在他们的跟踪器上也存在类似的问题,不确定是您还是其他人。但是为什么你首先需要使用它呢?您想要实现哪些常规 Vaadin 应用程序无法实现的目标,并且您需要嵌入多个 UI?


详细版

所以我做了一些挖掘,你的观察是正确的,/VAADIN/路径中丢失了。在 Spring Boot 应用程序中可能还会处理其他失败的请求 vaadinServlet,例如 heartbeat 和 uidl。

独立应用程序请求:

独立应用请求

嵌入式应用请求:

嵌入式应用请求

通过一点模式调试,似乎插件确实使用了不正确的路径: 不正确的路径

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

在我看来,这是插件中的一个错误,但可能只有开发人员才能确认或解释为什么会这样。

正则表达式替换

作为一种解决方法,我们可以使用 spring 控制器将请求重定向到正确的 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);
    }
}
于 2017-08-04T00:45:56.113 回答