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

Posted

技术标签:

【中文标题】使用 Guice 和 Undertow 在 Camel 中使用 rest Servlet【英文标题】:Using rest Servlet in Camel with Guice and Undertow 【发布时间】:2015-12-31 20:33:40 【问题描述】:

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

我在应用容器中使用 spring 和 servlet3.0 完成了这项工作。

在扩展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

【问题讨论】:

【参考方案1】:

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

我怀疑我一直使用 .component("servlet") 而不是 .component("RestServlet"),但 Camel 之前不会自动链接。

我将此部分更改为

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

我将 servlet 映射更改为 /* 的部署,否则 request.getPathInfo() 将在 CamelHttpTransportServlet 内返回 null。 注意我遇到了一个问题,因为我最初将 contextPath 设置为 /rest/* 这弄乱了会话和 cookie

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

【讨论】:

以上是关于使用 Guice 和 Undertow 在 Camel 中使用 rest Servlet的主要内容,如果未能解决你的问题,请参考以下文章

Guice、JDBC 和管理数据库连接

使用 Guice 实现 Restlet

Guice绑定和FactoryModuleBuilder

Guice vs AspectJ

TestNG 中使用 Guice 来进行依赖注入

Guice 和 Servlet - 一般理解问题?