通过 Guice 和 Undertow 在 Camel 中使用 rest Servlet

Using rest Servlet in Camel with Guice and Undertow

我正在使用 Undertow 设置和应用程序,我已经为静态文件设置了 ResourceHandler,并且 Servlet 由 apache-camel 用来公开 rest服务。

我在应用程序容器中使用 spring 和 servlet3.0 完成了此操作。

在 class 扩展 org.springframework.web.servlet.support.AbstractAnnotationConfigDispatcherServletInitializer

@Override
public void onStartup(ServletContext servletContext) throws ServletException
{
    super.onStartup(servletContext);
    ServletRegistration.Dynamic servlet = servletContext.addServlet("RestServlet", new CamelHttpTransportServlet());
    servlet.setLoadOnStartup(1);
    servlet.addMapping("/rest/*");
}

骆驼路线

restConfiguration()
            .component("RestServlet")
            .bindingMode(RestBindingMode.json)
            .dataFormatProperty("prettyPrint", "true");

非常接近http://camel.apache.org/servlet.html

中描述的内容

但是如果我在 Undertow 中作为嵌入式执行此操作,我会得到 org.apache.camel.NoSuchBeanException: No bean could be found in the registry for: RestServlet of type: org.apache.camel.spi.RestConsumerFactory 因为我猜 Guice 永远找不到由 Undertow 创建的 servlet。我尝试手动将 CamelHttpTransportServlet 公开为 Guice 绑定,但这似乎并没有改变什么。

ClassLoader classLoader = getClass().getClassLoader();
    ResourceHandler staticHandler = new ResourceHandler(new ClassPathResourceManager(classLoader, STATIC_RESOURCE_ROOT))
            .addWelcomeFiles(INDEX_HTML);

    DeploymentInfo deploymentInfo = Servlets.deployment()
            .setClassLoader(classLoader)
            .setContextPath(ROOT_MAPPING)
            .setDeploymentName(DEPLOYMENT_NAME)
            .addServlet(
                    Servlets.servlet("RestServlet", CamelHttpTransportServlet.class)
                            .addMapping(REST_MAPPING)
                            .setLoadOnStartup(1)
            );

    DeploymentManager manager = Servlets.defaultContainer().addDeployment(deploymentInfo);
    manager.deploy();

    PathHandler path = Handlers.path()
            .addPrefixPath(REST_MAPPING, manager.start())
            .addPrefixPath(ROOT_MAPPING, staticHandler);

    undertow = Undertow.builder()
            .addHttpListener(port, LOCALHOST)
            .setHandler(path)
            .build();
    undertow.start();

静态资源按预期工作,其余 servlet 似乎也是 运行 并获得响应,但 CamelContext 无法启动。

我不能在 camel 中使用 restlet 或任何东西,因为端口将被使用,所以我需要为静态文件和 rest 使用不同的端口。 有没有办法让骆驼识别由Undertow发起的Servlet

好吧,我终于找到问题所在了。

我怀疑我一直使用 .component("servlet") 而不是 .component("RestServlet"),但 Camel 以前不会自动 link 这个。

我将此部分更改为

restConfiguration()
            .bindingMode(RestBindingMode.json)
            .component("servlet")
            .dataFormatProperty("prettyPrint", "true")
            .endpointProperty("servletName", "RestServlet);

并且我将 servlet 映射更改为 /* 的部署,否则 request.getPathInfo() 将在 CamelHttpTransportServlet 中 return null。 注意我遇到了一个问题,因为我最初将 contextPath 设置为 /rest/*,这搞砸了会话和 cookies

DeploymentInfo deploymentInfo = Servlets.deployment()
            .setClassLoader(classLoader)
            .setContextPath("/rest/")
            .setDeploymentName(DEPLOYMENT_NAME)
            .addServlet(
                    Servlets.servlet("RestServlet", CamelHttpTransportServlet.class)
                            .addMapping("/*")
                            .setLoadOnStartup(1)
            );