如何让Camel REST DSL在默认8080端口正常运行?
我正在尝试用XML编写Camel REST DSL,代码如下:
<camelContext xmlns="http://camel.apache.org/schema/blueprint"> <restConfiguration component="restlet"/> <rest path="/say"> <get uri="/hello"> <to uri="direct:hello"/> </get> </rest> <route> <from uri="direct:hello"/> <transform> <constant>Hello World</constant> </transform> </route> </camelContext>
这段代码手动指定其他端口时均可正常运行,但无法在默认8080端口运行。我希望服务能通过http://localhost:8080/say/hello访问,曾尝试手动配置端口:
<restConfiguration component="restlet" port="8080"/>
但出现如下错误日志:
JBWEB000065: HTTP Status 500 - JBWEB000263: Servlet.init() for servlet CXFServlet threw exceptionJBWEB000309: type JBWEB000066: Exception report
JBWEB000068: message JBWEB000263: Servlet.init() for servlet CXFServlet threw exception
JBWEB000069: description JBWEB000145: The server encountered an internal error that prevented it from fulfilling this request.
JBWEB000070: exception
javax.servlet.ServletException: JBWEB000263: Servlet.init() for servlet CXFServlet threw exception org.jboss.as.web.security.SecurityContextAssociationValve.invoke(SecurityContextAssociationValve.java:169) org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:97) org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:343) org.apache.coyote.http11.Http11Processor.process(Http11Processor.java:856) org.apache.coyote.http11.Http11Protocol$Http11ConnectionHandler.process(Http11Protocol.java:656) org.apache.tomcat.util.net.JIoEndpoint$Worker.run(JIoEndpoint.java:926) java.lang.Thread.run(Thread.java:748)JBWEB000071: root cause
org.springframework.beans.factory.NoSuchBeanDefinitionException: No bean named 'cxf' is defined org.springframework.beans.factory.support.DefaultListableBeanFactory.getBeanDefinition(DefaultListableBeanFactory.java:575) org.springframework.beans.factory.support.AbstractBeanFactory.getMergedLocalBeanDefinition(AbstractBeanFactory.java:1111) org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:276) org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:195) org.springframework.context.support.AbstractApplicationContext.getBean(AbstractApplicationContext.java:1127) org.apache.cxf.transport.servlet.CXFServlet.loadBus(CXFServlet.java:80) org.apache.cxf.transport.servlet.CXFNonSpringServlet.init(CXFNonSpringServlet.java:77) org.jboss.as.web.security.SecurityContextAssociationValve.invoke(SecurityContextAssociationValve.java:169) org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:97) org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:343) org.apache.coyote.http11.Http11Processor.process(Http11Processor.java:856) org.apache.coyote.http11.Http11Protocol$Http11ConnectionHandler.process(Http11Protocol.java:656) org.apache.tomcat.util.net.JIoEndpoint$Worker.run(JIoEndpoint.java:926) java.lang.Thread.run(Thread.java:748)
现在求助如何让该服务在默认8080端口正常运行。
解决方案
先给你拆解下错误根源:日志里的NoSuchBeanDefinitionException: No bean named 'cxf' is defined说明你的JBoss服务器已经默认在8080端口配置了CXFServlet,但你的项目里并没有引入对应的CXF Bean,同时你又试图用Restlet绑定8080端口,两者产生了端口冲突,容器启动时错误地去初始化CXFServlet导致失败。
下面给你几个可行的解决办法:
1. 改用CXF作为REST组件(最推荐)
既然服务器已经默认支持CXF,直接替换Restlet为CXF组件,这样就能复用8080端口的现有配置,完全避免冲突。修改你的Camel配置如下:
<camelContext xmlns="http://camel.apache.org/schema/blueprint"> <!-- 使用cxf组件,自动复用容器的8080端口 --> <restConfiguration component="cxf" port="8080"/> <rest path="/say"> <get uri="/hello"> <to uri="direct:hello"/> </get> </rest> <route> <from uri="direct:hello"/> <transform> <constant>Hello World</constant> </transform> </route> </camelContext>
记得确保你的项目依赖中包含camel-cxf的jar包(如果是Maven项目,添加对应的依赖项)。
2. 调整Restlet的使用方式
如果坚持要用Restlet,有两个选项:
- 选项A:移除JBoss中的CXFServlet配置:找到JBoss的web.xml或者相关部署配置文件,删除CXFServlet的注册项,这样8080端口就可以被Restlet使用。不过这种方式可能影响其他依赖CXF的服务,需要谨慎操作。
- 选项B:将Restlet部署为Servlet:不要让Restlet启动独立的HTTP服务器,而是把它作为Servlet部署到JBoss的8080端口。需要在项目的
web.xml中添加如下配置:
<servlet> <servlet-name>RestletServlet</servlet-name> <servlet-class>org.restlet.ext.servlet.ServerServlet</servlet-class> <init-param> <param-name>org.restlet.application</param-name> <!-- 替换成你的Camel REST应用类路径 --> <param-value>com.yourpackage.YourCamelRestApp</param-value> </init-param> </servlet> <servlet-mapping> <servlet-name>RestletServlet</servlet-name> <url-pattern>/say/*</url-pattern> </servlet-mapping>
然后创建对应的Camel REST应用类来绑定你的路由,这种方式也能复用8080端口,避免冲突。
3. 临时测试方案(不推荐用于生产)
如果只是临时测试,可以修改Restlet的端口为其他未被占用的端口,但这不符合你要使用8080的需求,所以只作为验证问题的手段。
内容的提问来源于stack exchange,提问作者Abhinav Sundaram




