You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

如何让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 exception

JBWEB000309: 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

火山引擎 最新活动