Java:带有 Vaadin 11 框架的 Jetty 服务器
Java: Jetty server with Vaadin 11 framework
我的目标是配置 Jetty 服务器以使用 Vaadin 11 框架。
我正在尝试的是以下内容:
public static void main(final String[] args) {
final Server server = new Server();
final ServerConnector httpConnector = new ServerConnector(server);
httpConnector.setPort(8080);
final ServletContextHandler contextHandler = new ServletContextHandler(ServletContextHandler.SESSIONS);
contextHandler.setContextPath("/");
final ServletHolder servletHolder = new ServletHolder(new VaadinServlet());
contextHandler.addServlet(servletHolder, "/*");
final WebAppContext context = new WebAppContext();
context.setServer(server);
context.setContextPath("/");
context.setClassLoader(Thread.currentThread().getContextClassLoader());
server.addConnector(httpConnector);
server.setHandler(contextHandler);
server.setHandler(context);
try {
server.start();
} catch (final Exception e) {
e.printStackTrace();
}
}
@Route("/")
public class MainView extends Div {
public MainView() {
System.out.println("main");
setText("aha bye");
}
}
但是从未调用 MainView。
我如何告诉 Jetty 将请求转发给 Vaadin?
server.setHandler(contextHandler);
server.setHandler(context);
您用该代码用 context
替换了 contextHandler
。
试试这个...
HandlerList handlers = new HandlerList();
handlers.addHandler(contextHandler);
handlers.addHandler(context);
handlers.addHandler(new DefaultHandler()); // to report errors if nothing above matches
server.setHandler(handlers);
但这仍然无法如您所愿。
为什么?因为在同一个 contextPath /
.
上有 2 个不同的上下文(contextHandler
和 context
)
将使用您 HandlerList
中的第一个上下文,而永远不会调用下一个。
为什么?因为一旦进入上下文,就不会退出(该上下文必须提供响应,甚至是错误)。
您可以修改 WebAppContext
以包含 VaadinServlet
(完全不需要 ServletContextHandler
)
例如:
final WebAppContext context = new WebAppContext();
final ServletHolder servletHolder = new ServletHolder(new VaadinServlet());
context.addServlet(servletHolder, "/*");
但是,这似乎又回到了wards,因为您的 WebAppContext
没有资源库或 war 声明,所以它在您的示例代码中没有为您做任何事情。
如果是我,我正在使用 embedded-jetty,我会完全避免使用 WebAppContext
,只坚持使用 ServletContextHandler
。
在这里回答我自己的问题。
But this will still not work as you expect. Why? Because you have 2 different contexts (contextHandler
and context
) on the same contextPath /
.
But again, this seems backwards, as your WebAppContext
has no resource base or war declared, so it's not doing anything for you in your sample code.
Joakim Erdfelt完全正确。我用两个上下文 和 弄乱了代码 我必须设置资源库或 war 文件。非常感谢您指出了解决方法!
也感谢 Leif Åstrand 提示找到所有带有 @Route
注释的 类!
我将服务器代码与“客户端”代码分开,并为码头服务器构建 war 文件。
我使用的工作解决方案如下:
final WebAppContext context = new WebAppContext();
context.setServer(httpServer);
context.setContextPath("/");
context.addServlet(new ServletHolder(new TestServlet()), "/*");
context.setWar(warFile.getAbsolutePath());
context.setExtractWAR(true);
context.setClassLoader(Thread.currentThread().getContextClassLoader());
context.setInitParameter("ui", MainUI.class.getCanonicalName());
httpServer.setHandler(context);
在Testservlet
(扩展VaadinServlet
)我有以下两种方法:
@SuppressWarnings("unchecked")
private void findRouteClasses() {
final Set<Class<?>> routeClasses = ReflectionUtils.findClassesWithAnnotation(Route.class,
"com.example.myproject");
this.routeClasses = new HashSet<>();
for (final Class<?> clazz : routeClasses)
this.routeClasses.add((Class<? extends Component>) clazz);
}
@Override
protected void servletInitialized() throws ServletException {
final ServletContext context = getServletContext();
final Object routeRegistryObject = context.getAttribute(RouteRegistry.class.getName());
if (routeRegistryObject == null)
throw new ServletException("routeRegistryObject is null");
if ((routeRegistryObject instanceof RouteRegistry) == false)
throw new ServletException("routeRegistryObject is not of type RouteRegistry");
final RouteRegistry routeRegistry = (RouteRegistry) routeRegistryObject;
findRouteClasses();
try {
routeRegistry.setNavigationTargets(routeClasses);
} catch (final InvalidRouteConfigurationException e) {
throw new ServletException(e);
}
super.servletInitialized();
}
所有类注解com.vaadin.flow.router.Route
被搜索然后设置为导航目标。
我的目标是配置 Jetty 服务器以使用 Vaadin 11 框架。
我正在尝试的是以下内容:
public static void main(final String[] args) {
final Server server = new Server();
final ServerConnector httpConnector = new ServerConnector(server);
httpConnector.setPort(8080);
final ServletContextHandler contextHandler = new ServletContextHandler(ServletContextHandler.SESSIONS);
contextHandler.setContextPath("/");
final ServletHolder servletHolder = new ServletHolder(new VaadinServlet());
contextHandler.addServlet(servletHolder, "/*");
final WebAppContext context = new WebAppContext();
context.setServer(server);
context.setContextPath("/");
context.setClassLoader(Thread.currentThread().getContextClassLoader());
server.addConnector(httpConnector);
server.setHandler(contextHandler);
server.setHandler(context);
try {
server.start();
} catch (final Exception e) {
e.printStackTrace();
}
}
@Route("/")
public class MainView extends Div {
public MainView() {
System.out.println("main");
setText("aha bye");
}
}
但是从未调用 MainView。 我如何告诉 Jetty 将请求转发给 Vaadin?
server.setHandler(contextHandler);
server.setHandler(context);
您用该代码用 context
替换了 contextHandler
。
试试这个...
HandlerList handlers = new HandlerList();
handlers.addHandler(contextHandler);
handlers.addHandler(context);
handlers.addHandler(new DefaultHandler()); // to report errors if nothing above matches
server.setHandler(handlers);
但这仍然无法如您所愿。
为什么?因为在同一个 contextPath /
.
contextHandler
和 context
)
将使用您 HandlerList
中的第一个上下文,而永远不会调用下一个。
为什么?因为一旦进入上下文,就不会退出(该上下文必须提供响应,甚至是错误)。
您可以修改 WebAppContext
以包含 VaadinServlet
(完全不需要 ServletContextHandler
)
例如:
final WebAppContext context = new WebAppContext();
final ServletHolder servletHolder = new ServletHolder(new VaadinServlet());
context.addServlet(servletHolder, "/*");
但是,这似乎又回到了wards,因为您的 WebAppContext
没有资源库或 war 声明,所以它在您的示例代码中没有为您做任何事情。
如果是我,我正在使用 embedded-jetty,我会完全避免使用 WebAppContext
,只坚持使用 ServletContextHandler
。
在这里回答我自己的问题。
But this will still not work as you expect. Why? Because you have 2 different contexts (
contextHandler
andcontext
) on the same contextPath/
.But again, this seems backwards, as your
WebAppContext
has no resource base or war declared, so it's not doing anything for you in your sample code.
Joakim Erdfelt完全正确。我用两个上下文 和 弄乱了代码 我必须设置资源库或 war 文件。非常感谢您指出了解决方法!
也感谢 Leif Åstrand 提示找到所有带有 @Route
注释的 类!
我将服务器代码与“客户端”代码分开,并为码头服务器构建 war 文件。
我使用的工作解决方案如下:
final WebAppContext context = new WebAppContext();
context.setServer(httpServer);
context.setContextPath("/");
context.addServlet(new ServletHolder(new TestServlet()), "/*");
context.setWar(warFile.getAbsolutePath());
context.setExtractWAR(true);
context.setClassLoader(Thread.currentThread().getContextClassLoader());
context.setInitParameter("ui", MainUI.class.getCanonicalName());
httpServer.setHandler(context);
在Testservlet
(扩展VaadinServlet
)我有以下两种方法:
@SuppressWarnings("unchecked")
private void findRouteClasses() {
final Set<Class<?>> routeClasses = ReflectionUtils.findClassesWithAnnotation(Route.class,
"com.example.myproject");
this.routeClasses = new HashSet<>();
for (final Class<?> clazz : routeClasses)
this.routeClasses.add((Class<? extends Component>) clazz);
}
@Override
protected void servletInitialized() throws ServletException {
final ServletContext context = getServletContext();
final Object routeRegistryObject = context.getAttribute(RouteRegistry.class.getName());
if (routeRegistryObject == null)
throw new ServletException("routeRegistryObject is null");
if ((routeRegistryObject instanceof RouteRegistry) == false)
throw new ServletException("routeRegistryObject is not of type RouteRegistry");
final RouteRegistry routeRegistry = (RouteRegistry) routeRegistryObject;
findRouteClasses();
try {
routeRegistry.setNavigationTargets(routeClasses);
} catch (final InvalidRouteConfigurationException e) {
throw new ServletException(e);
}
super.servletInitialized();
}
所有类注解com.vaadin.flow.router.Route
被搜索然后设置为导航目标。