Java: сервер Jetty с фреймворком Vaadin 11 - PullRequest
0 голосов
/ 19 октября 2018

Моя цель - настроить сервер 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?

Ответы [ 2 ]

0 голосов
/ 21 октября 2018

Отвечая на мой собственный вопрос здесь.

Но это все равно не будет работать, как вы ожидаете.Зачем?Поскольку у вас есть 2 разных контекста (contextHandler и context) в одном и том же contextPath /.

Но, опять же, это кажется задом наперед, поскольку у вашего WebAppContext нет базы ресурсов или объявленной войны, поэтомуон ничего не делает для вас в вашем примере кода.

Joakim Erdfelt абсолютно прав.Я перепутал код с двумя контекстами и . Мне нужно либо установить базу ресурсов, либо файл войны.Большое спасибо вам за то, что вы указали путь к решению!

Спасибо Лейфу Астранду также за подсказку найти все классы с аннотацией @Route!

Я отделил код сервера от кода «клиента» и создал war-файл для сервера Jetty.

В качестве рабочего решения я использую следующее:

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);

InTestservlet (расширение 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 отправляются в поиск и затем устанавливаются в качестве целей навигации.

0 голосов
/ 19 октября 2018
server.setHandler(contextHandler);
server.setHandler(context);

Вы заменили 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);    

Но это все равно не будет работать, как выожидать.Зачем?Поскольку у вас есть 2 разных контекста (contextHandler и context) в одном и том же contextPath /.

Будет использован первый контекст в вашем HandlerList, а следующий никогда не будет вызван.Зачем?Поскольку после ввода контекста вы не выходите из него (этот контекст ДОЛЖЕН служить ответом, даже ошибкой).

Вы можете просто изменить свой WebAppContext, включив в него VaadinServlet (устраняя необходимость вServletContextHandler полностью)

например:

final WebAppContext context = new WebAppContext();
final ServletHolder servletHolder = new ServletHolder(new VaadinServlet());
context.addServlet(servletHolder, "/*");

Но, опять же, это кажется задом наперед, поскольку у вашего WebAppContext нет базы ресурсов или объявленной войны, поэтому он ничего не делает для вас вВаш пример кода.

Если бы это был я, и я использую , я бы не стал использовать WebAppContext полностью и просто придерживался только ServletContextHandler.

...