通过 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)
);
我正在使用 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)
);