使用 apache camel 创建休息服务时出错
Posted
技术标签:
【中文标题】使用 apache camel 创建休息服务时出错【英文标题】:Getting error while creating rest service using apache camel 【发布时间】:2015-03-20 20:49:06 【问题描述】:由于我对 Apache camel 尤其是 Rest DSL 非常陌生,因此我想尝试一个 Rest DSL 示例。
所以我创建了一个 camel-config.xml 为:
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:camel="http://camel.apache.org/schema/spring"
xsi:schemaLocation="
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
http://camel.apache.org/schema/spring http://camel.apache.org/schema/spring/camel-spring.xsd">
<!-- use camel-metrics route policy to gather metrics for all routes -->
<!-- bean id="metricsRoutePolicyFactory" class="org.apache.camel.component.metrics.routepolicy.MetricsRoutePolicyFactory"/-->
<!-- a rest service which uses binding to/from pojos -->
<bean id="userRoutes" class="org.apache.camel.example.rest.UserRouteBuilder"/>
<!-- a bean for user services -->
<bean id="userService" class="org.apache.camel.example.rest.UserService"/>
<camelContext id="myCamel" xmlns="http://camel.apache.org/schema/spring">
<routeBuilder ref="userRoutes"/>
</camelContext>
</beans>
我的路线类别是:
package org.apache.camel.example.rest;
import org.apache.camel.builder.RouteBuilder;
/**
* Define REST services using the Camel REST DSL
*/
public class UserRouteBuilder extends RouteBuilder
public void configure() throws Exception
rest("/say").get("/hello").to("direct:hello").get("/bye")
.consumes("application/json").to("direct:bye").post("/bye")
.to("mock:update");
from("direct:hello").transform().constant("Hello World");
from("direct:bye").transform().constant("Bye World");
我的 web.xml 是:
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" id="WebApp_ID" version="2.5">
<display-name>My Camel Rest Application</display-name>
<!-- location of Camel Spring xml files -->
<context-param>
<param-name>contextConfigLocation</param-name>
<!-- to use Java DSL -->
<param-value>classpath:camel-config.xml</param-value>
<!-- to use XML DSL, then enable me, and disable Java DSL above
<param-value>classpath:camel-config-xml.xml</param-value>
-->
</context-param>
<!-- the listener that kick-starts Spring -->
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
<!-- to setup Camel Servlet -->
<servlet>
<display-name>Camel Http Transport Servlet</display-name>
<servlet-name>CamelServlet</servlet-name>
<servlet-class>org.apache.camel.component.servlet.CamelHttpTransportServlet</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>
<!-- START SNIPPET: e1 -->
<!-- to setup Camel Swagger api servlet -->
<servlet>
<servlet-name>ApiDeclarationServlet</servlet-name>
<servlet-class>org.apache.camel.component.swagger.DefaultCamelSwaggerServlet</servlet-class>
<init-param>
<!-- we specify the base.path using relative notation, that means the actual path will be calculated at runtime as
http://server:port/contextpath/rest -->
<param-name>base.path</param-name>
<param-value>rest</param-value>
</init-param>
<init-param>
<!-- we specify the api.path using relative notation, that means the actual path will be calculated at runtime as
http://server:port/contextpath/api-docs -->
<param-name>api.path</param-name>
<param-value>api-docs</param-value>
</init-param>
<init-param>
<param-name>api.version</param-name>
<param-value>1.2.3</param-value>
</init-param>
<init-param>
<param-name>api.title</param-name>
<param-value>User Services</param-value>
</init-param>
<init-param>
<param-name>api.description</param-name>
<param-value>Camel Rest Example with Swagger that provides an User REST service</param-value>
</init-param>
<load-on-startup>2</load-on-startup>
</servlet>
<!-- swagger api declaration -->
<servlet-mapping>
<servlet-name>ApiDeclarationServlet</servlet-name>
<url-pattern>/api-docs/*</url-pattern>
</servlet-mapping>
<!-- END SNIPPET: e1 -->
<!-- define that url path for the Camel Servlet to use -->
<servlet-mapping>
<servlet-name>CamelServlet</servlet-name>
<url-pattern>/rest/*</url-pattern>
</servlet-mapping>
<!-- START SNIPPET: e2 -->
<!-- enable CORS filter so people can use swagger ui to browse and test the apis -->
<filter>
<filter-name>RestSwaggerCorsFilter</filter-name>
<filter-class>org.apache.camel.component.swagger.RestSwaggerCorsFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>RestSwaggerCorsFilter</filter-name>
<url-pattern>/api-docs/*</url-pattern>
<url-pattern>/rest/*</url-pattern>
</filter-mapping>
<!-- END SNIPPET: e2 -->
<welcome-file-list>
<welcome-file>home.html</welcome-file>
</welcome-file-list>
</web-app>
现在我创建了我的restProject 的war 文件,并将它部署在tomcat 上。在tomcat的lib文件夹中提供了所有必需的jar。我正在使用骆驼 2.14。
现在当我启动我的 tomcat 时,在启动过程中我得到错误:
SEVERE: Context initialization failed
org.apache.camel.RuntimeCamelException: java.lang.IllegalStateException: Cannot find RestConsumerFactory in Registry or
as a Component to use
at org.apache.camel.util.ObjectHelper.wrapRuntimeCamelException(ObjectHelper.java:1364)
at org.apache.camel.spring.SpringCamelContext.onApplicationEvent(SpringCamelContext.java:122)
at org.apache.camel.spring.CamelContextFactoryBean.onApplicationEvent(CamelContextFactoryBean.java:327)
at org.springframework.context.event.SimpleApplicationEventMulticaster.multicastEvent(SimpleApplicationEventMult
icaster.java:96)
at org.springframework.context.support.AbstractApplicationContext.publishEvent(AbstractApplicationContext.java:3
34)
at org.springframework.context.support.AbstractApplicationContext.finishRefresh(AbstractApplicationContext.java:
948)
at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:482)
at org.springframework.web.context.ContextLoader.configureAndRefreshWebApplicationContext(ContextLoader.java:389
)
at org.springframework.web.context.ContextLoader.initWebApplicationContext(ContextLoader.java:294)
at org.springframework.web.context.ContextLoaderListener.contextInitialized(ContextLoaderListener.java:112)
at org.apache.catalina.core.StandardContext.listenerStart(StandardContext.java:4791)
at org.apache.catalina.core.StandardContext.startInternal(StandardContext.java:5285)
at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:150)
at org.apache.catalina.core.ContainerBase.addChildInternal(ContainerBase.java:901)
at org.apache.catalina.core.ContainerBase.addChild(ContainerBase.java:877)
at org.apache.catalina.core.StandardHost.addChild(StandardHost.java:618)
at org.apache.catalina.startup.HostConfig.deployDirectory(HostConfig.java:1100)
at org.apache.catalina.startup.HostConfig$DeployDirectory.run(HostConfig.java:1618)
at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:471)
at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:334)
at java.util.concurrent.FutureTask.run(FutureTask.java:166)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1110)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:603)
at java.lang.Thread.run(Thread.java:722)
Caused by: java.lang.IllegalStateException: Cannot find RestConsumerFactory in Registry or as a Component to use
at org.apache.camel.component.rest.RestEndpoint.createConsumer(RestEndpoint.java:238)
at org.apache.camel.impl.EventDrivenConsumerRoute.addServices(EventDrivenConsumerRoute.java:65)
at org.apache.camel.impl.DefaultRoute.onStartingServices(DefaultRoute.java:80)
at org.apache.camel.impl.RouteService.warmUp(RouteService.java:134)
at org.apache.camel.impl.DefaultCamelContext.doWarmUpRoutes(DefaultCamelContext.java:2379)
at org.apache.camel.impl.DefaultCamelContext.safelyStartRouteServices(DefaultCamelContext.java:2309)
at org.apache.camel.impl.DefaultCamelContext.doStartOrResumeRoutes(DefaultCamelContext.java:2091)
at org.apache.camel.impl.DefaultCamelContext.doStartCamel(DefaultCamelContext.java:1951)
at org.apache.camel.impl.DefaultCamelContext.doStart(DefaultCamelContext.java:1777)
at org.apache.camel.support.ServiceSupport.start(ServiceSupport.java:61)
at org.apache.camel.impl.DefaultCamelContext.start(DefaultCamelContext.java:1745)
at org.apache.camel.spring.SpringCamelContext.maybeStart(SpringCamelContext.java:254)
at org.apache.camel.spring.SpringCamelContext.onApplicationEvent(SpringCamelContext.java:120)
... 22 more
我在过去两天试图弄清楚为什么我会收到这个错误。 真的很期待你的解决方案。提前谢谢..
【问题讨论】:
【参考方案1】:如果您正在运行Camel-Spring Boot application,您可以通过在 pom.xml 中添加以下依赖项来解决此问题:
<dependency>
<groupId>org.apache.camel.springboot</groupId>
<artifactId>camel-http-starter</artifactId>
</dependency>
【讨论】:
【参考方案2】:您需要对其余 DSL 进行额外配置。 http://camel.apache.org/rest-dsl.html 中描述的 4 个组件支持 rest DSL。请查看 [支持 Rest DSL 的组件]部分。有关配置,请查看 [配置 Rest DSL] 部分
您实际上需要的是另外 2 个添加。
1) 在您的路线构建器中,有一个休息配置部分。对于可能是 restConfiguration().component("servlet")
的 servlet 组件 ->这里有更多选项。
在这个example中找到完整的配置
2) 在 pom.xml 中添加依赖。
<dependency>
<groupId>org.apache.camel</groupId>
<artifactId>camel-servlet</artifactId>
</dependency>
有关 spark-rest 配置,请查看代码 here
【讨论】:
以上是关于使用 apache camel 创建休息服务时出错的主要内容,如果未能解决你的问题,请参考以下文章
错误:在类路径上找到多个RestConsumerFactory
Apache Camel http组件计时器dockerization
Apache Camel - 调用 http 或 rest 调用(通过 Shiro Security 过滤)