Java:Jetty服务器与vaadin11框架

Java:Jetty服务器与vaadin11框架,java,jetty,vaadin,embedded-jetty,Java,Jetty,Vaadin,Embedded Jetty,我的目标是将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 Servle

我的目标是将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");
    }
}
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);
但从未调用MainView。 如何告诉Jetty将请求转发给Vaadin?

server.setHandler(contextHandler);
setHandler(上下文);
您将
contextHandler
替换为
context
,并使用该代码

试试这个

HandlerList handlers = new HandlerList();
handlers.addHandler(contextHandler);
handlers.addHandler(context);
handlers.addHandler(new DefaultHandler()); // to report errors if nothing above matches
server.setHandler(handlers);    
但这仍然不会像你所期望的那样起作用。 为什么?因为在同一上下文路径上有两个不同的上下文(
contextHandler
context

将使用
HandlerList
中的第一个上下文,并且永远不会调用下一个上下文。 为什么?因为一旦您输入了一个上下文,您就不会退出它(该上下文必须提供响应,甚至是错误)

您可以修改
WebAppContext
以包含
VaadinServlet
(完全不需要
ServletContextHandler

例如:

但同样,这似乎是倒退的,因为您的
WebAppContext
没有资源库或已声明的war,所以它在示例代码中对您没有任何帮助

如果是我,并且我正在使用,我会完全避免使用
WebAppContext
,只使用
ServletContextHandler

server.setHandler(contextHandler);
setHandler(上下文);
您将
contextHandler
替换为
context
,并使用该代码

试试这个

HandlerList handlers = new HandlerList();
handlers.addHandler(contextHandler);
handlers.addHandler(context);
handlers.addHandler(new DefaultHandler()); // to report errors if nothing above matches
server.setHandler(handlers);    
但这仍然不会像你所期望的那样起作用。 为什么?因为在同一上下文路径上有两个不同的上下文(
contextHandler
context

将使用
HandlerList
中的第一个上下文,并且永远不会调用下一个上下文。 为什么?因为一旦您输入了一个上下文,您就不会退出它(该上下文必须提供响应,甚至是错误)

您可以修改
WebAppContext
以包含
VaadinServlet
(完全不需要
ServletContextHandler

例如:

但同样,这似乎是倒退的,因为您的
WebAppContext
没有资源库或已声明的war,所以它在示例代码中对您没有任何帮助


如果是我,并且我正在使用,我会完全避免使用
WebAppContext
,只使用
ServletContextHandler

回答我自己的问题

但这仍然不会像你所期望的那样起作用。为什么?因为在同一上下文路径上有两个不同的上下文(
contextHandler
context

但同样,这似乎是倒退的,因为您的
WebAppContext
没有资源库或已声明的war,所以它在示例代码中对您没有任何帮助

这是绝对正确的。我用两个上下文把代码搞乱了,我必须设置一个资源库或war文件。非常感谢您指出了解决方案的方法

感谢too提供了查找带有
@Route
注释的所有类的提示

我将服务器代码与“客户机”代码分离,并为jetty服务器构建war文件

我使用的工作解决方案如下:

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");
    }
}
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();
}
@SuppressWarnings(“未选中”)
私有的void类(){

最后一组在这里回答我自己的问题

但是这仍然不能像您预期的那样工作。为什么?因为在同一个contextPath上有两个不同的上下文(
contextHandler
context

但同样,这似乎是倒退的,因为您的
WebAppContext
没有资源库或已声明的war,所以它在示例代码中对您没有任何帮助

绝对正确。我在两个上下文中把代码弄乱了我必须设置资源库或war文件。非常感谢您指出解决方案的方法

感谢too提供了查找带有
@Route
注释的所有类的提示

我将服务器代码与“客户机”代码分离,并为jetty服务器构建war文件

我使用的工作解决方案如下:

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");
    }
}
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();
}
@SuppressWarnings(“未选中”)
私有的void类(){

由于我在手机上,最后的设置很短。您必须启用Jetty的注释扫描,以便它可以找到
@Route
注释类。可能还需要添加其他内容,以使其运行Vaadin的
ServletContainerInitializer
实现。谢谢@LeifÅstrand-我刚刚按照您描述的方式在这里发布了一个答案-谢谢!简短的回答,因为我在手机上。你必须启用Jetty的注释扫描,以便它可以找到
@Route
注释类。可能还需要添加其他内容,以使其运行Vaadin的
ServletContainerInitializer
实现。谢谢@LeifÅstrand-我刚刚在这里发布了一个答案,以及你描述的方式ibed-谢谢!