首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Java: Vaadin 11框架的Jetty服务器

Java: Vaadin 11框架的Jetty服务器
EN

Stack Overflow用户
提问于 2018-10-19 15:41:43
回答 2查看 277关注 0票数 0

我的目标是配置一个Jetty服务器来使用Vaadin 11框架。

我所做的尝试如下:

代码语言:javascript
复制
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?

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2018-10-21 07:06:57

在这里回答我自己的问题。

但这仍然不能像你期望的那样奏效。为什么?因为在同一个contextHandler /上有两个不同的上下文( contextPath和context)。 但是,这似乎是反向的,因为您的WebAppContext没有声明的资源基础或war,所以它在示例代码中没有为您做任何事情。

约基姆·埃尔德费特是绝对正确的。我用两个上下文()搅乱了代码,要么设置资源库,要么设置war文件。非常感谢你为我们指明了解决之道!

也要感谢莱夫·奥斯特兰给出的使用@Route注释查找所有类的提示!

我将服务器代码从“客户端”代码中分离出来,并为jetty服务器构建了war文件。

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

代码语言:javascript
复制
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)中,我有以下两个方法:

代码语言:javascript
复制
@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的类都被隔离,然后设置为导航目标。

票数 2
EN

Stack Overflow用户

发布于 2018-10-19 15:50:14

代码语言:javascript
复制
server.setHandler(contextHandler);
server.setHandler(context);

您将您的contextHandler替换为使用该代码的context

试试这个..。

代码语言:javascript
复制
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 /上有两个不同的上下文( contextPath和context)。

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

您只需修改WebAppContext以包含VaadinServlet (完全消除对ServletContextHandler的需求)

例:

代码语言:javascript
复制
final WebAppContext context = new WebAppContext();
final ServletHolder servletHolder = new ServletHolder(new VaadinServlet());
context.addServlet(servletHolder, "/*");

但是,这似乎是反向的,因为您的WebAppContext没有声明的资源基础或war,所以它在示例代码中没有为您做任何事情。

如果是我,而且我使用的是嵌入式码头,我将完全避免使用WebAppContext,而只使用ServletContextHandler

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/52895759

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档