嵌入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,所以我绝对可以使用一些帮助。
TL; DR;版本
这似乎是一个插件中的错误,并且有一个类似的issue open on their tracker,不知道它是你还是其他人。但为什么你首先需要使用它?你想要实现的是什么,这是常规的Vaadin应用程序无法完成的,你需要嵌入多个UI?
详细版本
所以我做了一些挖掘和你的观察是正确的,/VAADIN/
从路径丢失。在春季启动应用程序中,可能还会有其他由vaadinServlet
处理的失败请求,例如心跳和uidl。
单机应用程序请求:
嵌入式应用程序请求:
最后追溯到BAC k到./VAADIN
的错误正则表达式替换为http://localhost:9030/
而不是正确的http://localhost:9030/VAADIN
。
在我看来,就像它在附加的错误,但可能只有开发可以确认或解释为什么它正在这样做。
这样的工作,我们周围可以使用弹簧控制器重定向请求到正确的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);
}
}
感谢您的回答。 我需要使用附加组件作为UI组合问题的解决方案,因为我必须构建一些UI屏幕或页面来显示我的多个服务的UI(以便每个服务都可以拥有它自己的独立UI,并且可以访问没有“主机”应用程序)。 关于你的解决方案,我试着实现它,并做了一些测试: 控制器按照预期重定向所有请求,比如'localhost:8080/widgetsets/**';但不是'localhost:8080widgetsets/**',这是主机应用程序产生的URL。我不知道是否有可能的解决方案。 –
@ Zineb.elh是的,忘了这一点,在你的主机应用程序中添加一个'/'到启动应用程序url :-)。但请记住,它仍然在首次刷新时崩溃...还没有找到解决方案。 – Morfic
再次感谢您的帮助。我知道这不是问题的最终解决方案。我正在等待附加开发人员研究它。我试图理解每个请求发送的'v-uiId'的作用,以便解决这个问题。我注意到UI不会相互作用(即,当我点击一个按钮时不会改变)。这与'v-uiId'问题有关吗? –
没有检查的附加来源,但我有一种预感它的紧耦合的引导,很可能调度的servlet和servlet的Vaadin维护您的应用程序的要求。如果您可以提供[sscce](http://sscce.org)来轻松地重现您的问题,它可能会帮助您获得一些答案。 – Morfic
这是一个[链接](https://github.com/zelha/45465131-sscce.git)到一个存储库,我重现了错误,如果没关系。 –