Apache camel 有人能给我介绍一个使用cxfrs客户机/生产商的骆驼路线示例吗?
我很难让我的驼峰路线成功地将消息发布到现有的RESTful web服务。我已经尝试了camelcxf包中的所有示例,但没有一个生成web服务调用(它们是消费者)。我很想找到一个这样的工作示例,这样我就可以逐步完成CxfRsProducer的执行,希望能够发现为什么我的路由没有正确地发布到web服务 以下是我的RouteBuilder配置:Apache camel 有人能给我介绍一个使用cxfrs客户机/生产商的骆驼路线示例吗?,apache-camel,cxfrs,Apache Camel,Cxfrs,我很难让我的驼峰路线成功地将消息发布到现有的RESTful web服务。我已经尝试了camelcxf包中的所有示例,但没有一个生成web服务调用(它们是消费者)。我很想找到一个这样的工作示例,这样我就可以逐步完成CxfRsProducer的执行,希望能够发现为什么我的路由没有正确地发布到web服务 以下是我的RouteBuilder配置: public void configure() { //errorHandler(deadLetterChannel(String.format("f
public void configure()
{
//errorHandler(deadLetterChannel(String.format("file:%s/../errors", sourceFolder)).useOriginalMessage().retriesExhaustedLogLevel(LoggingLevel.DEBUG));
errorHandler(loggingErrorHandler());
/*
* JMS to WS route for some of the events broadcast to the jms topic
*/
Endpoint eventTopic = getContext().getEndpoint(String.format("activemq:topic:%s?clientId=%s&durableSubscriptionName=%s", eventTopicName, durableClientId, durableSubscriptionName));
from(eventTopic) // listening on the jms topic
.process(eventProcessor) // translate event into a Notifications object (JAX-RS annotated class)
.choice() // gracefully end the route if there is no translator for the event type
.when(header("hasTranslator").isEqualTo(false)).stop() // no translator stops the route
.otherwise() // send the notification to the web service
.to("cxfrs:bean:rsClient");
}
以下是rsClientBean:
<cxf:rsClient id="rsClient"
address="http://localhost/ws"
serviceClass="com.foo.notifications.NotificationsResource"
loggingFeatureEnabled="true" />
处理器创建一个通知对象以放入exechange消息正文:
private class EventProcessor implements Processor
{
@Override
public void process(Exchange exchange) throws Exception
{
Message in = exchange.getIn();
IEvent event = (IEvent) in.getBody();
Notifications notifications = null;
in.setHeader("hasTranslator", false);
in.setHeader("Content-Type", "application/xml");
in.setHeader(CxfConstants.CAMEL_CXF_RS_USING_HTTP_API, false);
// I've tried using the HTTP API as 'true', and that results in a 405 error instead of the null ptr.
INotificationTranslator translator = findTranslator(event);
if (translator != null)
{
notifications = translator.build(event);
in.setHeader("hasTranslator", true);
}
// replace the IEvent in the body with the translation
in.setBody(notifications);
exchange.setOut(in);
}
}
Notifications类用JAXB注释以进行序列化
@XmlRootElement(name = "ArrayOfnotification")
@XmlType
public class Notifications
{
private List<Notification> notifications = new ArrayList<>();
@XmlElement(name="notification")
public List<Notification> getNotifications()
{
return notifications;
}
public void setNotifications(List<Notification> notifications)
{
this.notifications = notifications;
}
public void addNotification(Notification notification)
{
this.notifications.add(notification);
}
}
@XmlRootElement(name=“ArrayOfnotification”)
@XmlType
公共类通知
{
私有列表通知=新建ArrayList();
@xmlement(name=“通知”)
公共列表getNotifications()
{
退货通知;
}
公共无效设置通知(列表通知)
{
this.notifications=通知;
}
公共无效添加通知(通知通知)
{
this.notifications.add(通知);
}
}
从web服务返回的错误:
Exchange
---------------------------------------------------------------------------------------------------------------------------------------
Exchange[
Id ID-PWY-EHANSEN-01-62376-1407805689371-0-50
ExchangePattern InOnly
Headers {breadcrumbId=ID:EHANSEN-01-62388-1407805714469-3:1:1:1:47, CamelCxfRsUsingHttpAPI=false, CamelRedelivered=false, CamelRedeliveryCounter=0, Content-Type=application/xml, hasTranslator=true, JMSCorrelationID=null, JMSDeliveryMode=2, JMSDestination=topic://SysManEvents, JMSExpiration=1407805812574, JMSMessageID=ID:EHANSEN-01-62388-1407805714469-3:1:1:1:47, JMSPriority=4, JMSRedelivered=false, JMSReplyTo=null, JMSTimestamp=1407805782574, JMSType=null, JMSXGroupID=null, JMSXUserID=null}
BodyType com.ehansen.notification.types.v2.Notifications
Body <?xml version="1.0" encoding="UTF-8"?><ArrayOfnotification xmlns="http://schemas.datacontract.org/2004/07/ehansen.Notifications.Dto"> <notification> <causeType>EVENT_NAME</causeType> <causeValue>DeviceEvent</causeValue> <details> <notificationDetail> <name>BUSY</name> <value>false</value> <unit>boolean</unit> </notificationDetail> <notificationDetail> <name>DESCRIPTION</name> <value>Software Computer UPS Unit</value> <unit>name</unit> </notificationDetail> <notificationDetail> <name>DEVICE_NUMBER</name> <value>1</value> <unit>number</unit> </notificationDetail> <notificationDetail> <name>DEVICE_SUB_TYPE</name> <value>1</value> <unit>type</unit> </notificationDetail> <notificationDetail> <name>DEVICE_TYPE</name> <value>UPS</value> <unit>type</unit> </notificationDetail> <notificationDetail> <name>FAULTED</name> <value>false</value> <unit>boolean</unit> </notificationDetail> <notificationDetail> <name>RESPONDING</name> <value>true</value> <unit>boolean</unit> </notificationDetail> <notificationDetail> <name>STORAGE_UNIT_NUMBER</name> <value>1</value> <unit>number</unit> </notificationDetail> </details> <sourceType>DEVICE_ID</sourceType> <sourceValue>1:UPS:1</sourceValue> <time>2014-08-11T18:09:42.571-07:00</time> </notification></ArrayOfnotification>
]
Stacktrace
---------------------------------------------------------------------------------------------------------------------------------------
java.lang.NullPointerException
at java.lang.Class.searchMethods(Class.java:2670)
at java.lang.Class.getMethod0(Class.java:2694)
at java.lang.Class.getMethod(Class.java:1622)
at org.apache.camel.component.cxf.jaxrs.CxfRsProducer.findRightMethod(CxfRsProducer.java:266)
at org.apache.camel.component.cxf.jaxrs.CxfRsProducer.invokeProxyClient(CxfRsProducer.java:222)
at org.apache.camel.component.cxf.jaxrs.CxfRsProducer.process(CxfRsProducer.java:90)
at org.apache.camel.util.AsyncProcessorConverterHelper$ProcessorToAsyncProcessorBridge.process(AsyncProcessorConverterHelper.java:61)
at org.apache.camel.processor.SendProcessor$2.doInAsyncProducer(SendProcessor.java:143)
at org.apache.camel.impl.ProducerCache.doInAsyncProducer(ProducerCache.java:307)
at org.apache.camel.processor.SendProcessor.process(SendProcessor.java:138)
交换
---------------------------------------------------------------------------------------------------------------------------------------
交换[
Id-PWY-EHANSEN-01-62376-1407805689371-0-50
仅交换模式
标题{breadcrumbId=ID:EHANSEN-01-62388-1407805714469-3:1:1:1:47,camelcxfrsusingttpapi=false,CamelRedelivered=false,CamelRedeliveryCounter=0,Content-Type=application/xml,hasttranslator=true,JMSCorrelationID=null,JMSDeliveryMode=2,JMSDestination=topic://SysManEvents,jmsemessageid=ID:EHANSEN-01-62388-1407805714469-3:1:1:1:47,JMSPriority=4,jmsrelivered=false,JMSReplyTo=null,jmstiestamp=1407805782574,JMSType=null,JMSXGroupID=null,JMSXUserID=null}
BodyType com.ehansen.notification.types.v2.Notifications
车身事件\u名称设备事件忙错误布尔描述软件计算机UPS装置名称设备\u编号1编号设备\u子类型1类型设备\u类型UPS类型错误布尔值响应真布尔值存储\u单元\u编号1编号设备\u ID1:UPS:12014-08-11T18:09:42.571-07:00
]
堆栈跟踪
---------------------------------------------------------------------------------------------------------------------------------------
java.lang.NullPointerException
位于java.lang.Class.searchMethods(Class.java:2670)
位于java.lang.Class.getMethod0(Class.java:2694)
位于java.lang.Class.getMethod(Class.java:1622)
位于org.apache.camel.component.cxf.jaxrs.CxfRsProducer.findRightMethod(CxfRsProducer.java:266)
位于org.apache.camel.component.cxf.jaxrs.CxfRsProducer.invokeProxyClient(CxfRsProducer.java:222)
位于org.apache.camel.component.cxf.jaxrs.CxfRsProducer.process(CxfRsProducer.java:90)
位于org.apache.camel.util.AsyncProcessorConverterHelper$ProcessorToAsyncProcessorBridge.process(AsyncProcessorConverterHelper.java:61)
位于org.apache.camel.processor.SendProcessor$2.doInAsyncProducer(SendProcessor.java:143)
位于org.apache.camel.impl.ProducerCache.doInAsyncProducer(ProducerCache.java:307)
位于org.apache.camel.processor.SendProcessor.process(SendProcessor.java:138)
CxfRsProducer类的以下方法中的methodName参数为null…因此我假设我的rsClient中存在一些配置不正确的地方
private Method findRightMethod(List<Class<?>> resourceClasses, String methodName, Class<?>[] parameterTypes) throws NoSuchMethodException {
Method answer = null;
for (Class<?> clazz : resourceClasses) {
try {
answer = clazz.getMethod(methodName, parameterTypes);
} catch (NoSuchMethodException ex) {
// keep looking
} catch (SecurityException ex) {
// keep looking
}
if (answer != null) {
return answer;
}
}
throw new NoSuchMethodException("Cannot find method with name: " + methodName + " having parameters: " + arrayToString(parameterTypes));
}
private方法findRightMethod(List[]参数类型)抛出NoSuchMethodException{
方法答案=null;
对于(类类别:资源类){
试一试{
answer=clazz.getMethod(方法名,参数类型);
}catch(NoSuchMethodException-ex){
//继续找
}catch(SecurityException-ex){
//继续找
}
如果(回答!=null){
返回答案;
}
}
抛出新的NoSuchMethodException(“找不到名为:+methodName+”且参数为:+arrayToString(parameterTypes))的方法”;
}
感谢所有人提供的帮助!serviceClass是一个带注释的Java类,定义REST web服务的操作
配置CXF REST客户端时,必须指定和地址以及serviceClass。通过检查serviceClass上的批注,CXF客户端代理知道在指定地址上发布的REST服务上应该有哪些REST操作
因此,在您的情况下,需要将.setHeader.setHeader(CxfConstants.OPERATION_NAME,“postNotification”);中的
添加到EventProcessor中,以告诉camel您要调用服务类的哪个方法。好的。这是camel配置xml文件
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://w3.org/2001/XMLSchema-instance"
xmlns:cxf="http://camel.apache.org/schema/cxf"
xmlns:jaxrs="http://cxf.apache.org/jaxrs"
xsi:schemaLocation="
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://camel.apache.org/schema/cxf
http://camel.apache.org/schema/cxf/camel-cxf.xsd
http://cxf.apache.org/jaxrs
http://cxf.apache.org/schemas/jaxrs.xsd
http://camel.apache.org/schema/spring
http://camel.apache.org/schema/spring/camel-spring.xsd
>
<import resource="classpath:META-INF/cxf/cxf.xml" />
<import resource="classpath:META-INF/cxf/cxf-servlet.xml" />
<bean id="helloBean" class="com.examples.camel.cxf.rest.resource.HelloWorldResource" />
<cxf:rsServer id="helloServer" address="/helloapp" loggingFeatureEnabled="true">
<cxf:serviceBeans>
<ref bean="helloBean" />
</cxf:serviceBeans>
<cxf:providers>
<bean class="org.codehaus.jackson.jaxrs.JacksonJsonProvider" />
</cxf:providers>
</cxf:rsServer>
<camelContext id="context" xmlns="http://camel.apache.org/schema/spring">
<route>
<from uri="cxfrs:bean:helloServer />
<log message="Processing CXF route....http method ${header.CamelHttpMethod}" />
<log message="Processing CXF route....path is ${header.CamelHttpPath}" />
<log message="Processing CXF route....body is ${body}" />
<choice>
<when>
<simple>${header.operationName} == 'sayHello'</simple>
<to uri="direct:invokeSayHello" />
</when>
<when>
<simple>${header.operationName} == 'greet'</simple>
<to uri="direct:invokeGreet" />
</when>
</choice>
</route>
<route id="invokeSayHello">
<from uri="direct:invokeSayHello" />
<bean ref="helloBean" method="sayHello" />
</route>
<route id="invokeGreet">
<from uri="direct:invokeGreet" />
<bean ref="helloBean" method="greet" />
</route>
</camelContext>
</beans>
您不需要,而且需要提供cxf:rsServer>。
仅标记就足以处理web服务请求和调用路由
如果两者都有,那么调用前者将无助于执行路由。要调用路由,请求必须到达发布的地址
希望这有帮助。如果可能,请提供maven项目示例。这是我之前编写的带有spring security的camel cxfrs示例-。请查看是否有帮助。谢谢!!设置操作名称就是我的全部任务
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://w3.org/2001/XMLSchema-instance"
xmlns:cxf="http://camel.apache.org/schema/cxf"
xmlns:jaxrs="http://cxf.apache.org/jaxrs"
xsi:schemaLocation="
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://camel.apache.org/schema/cxf
http://camel.apache.org/schema/cxf/camel-cxf.xsd
http://cxf.apache.org/jaxrs
http://cxf.apache.org/schemas/jaxrs.xsd
http://camel.apache.org/schema/spring
http://camel.apache.org/schema/spring/camel-spring.xsd
>
<import resource="classpath:META-INF/cxf/cxf.xml" />
<import resource="classpath:META-INF/cxf/cxf-servlet.xml" />
<bean id="helloBean" class="com.examples.camel.cxf.rest.resource.HelloWorldResource" />
<cxf:rsServer id="helloServer" address="/helloapp" loggingFeatureEnabled="true">
<cxf:serviceBeans>
<ref bean="helloBean" />
</cxf:serviceBeans>
<cxf:providers>
<bean class="org.codehaus.jackson.jaxrs.JacksonJsonProvider" />
</cxf:providers>
</cxf:rsServer>
<camelContext id="context" xmlns="http://camel.apache.org/schema/spring">
<route>
<from uri="cxfrs:bean:helloServer />
<log message="Processing CXF route....http method ${header.CamelHttpMethod}" />
<log message="Processing CXF route....path is ${header.CamelHttpPath}" />
<log message="Processing CXF route....body is ${body}" />
<choice>
<when>
<simple>${header.operationName} == 'sayHello'</simple>
<to uri="direct:invokeSayHello" />
</when>
<when>
<simple>${header.operationName} == 'greet'</simple>
<to uri="direct:invokeGreet" />
</when>
</choice>
</route>
<route id="invokeSayHello">
<from uri="direct:invokeSayHello" />
<bean ref="helloBean" method="sayHello" />
</route>
<route id="invokeGreet">
<from uri="direct:invokeGreet" />
<bean ref="helloBean" method="greet" />
</route>
</camelContext>
</beans>
import javax.ws.rs.core.Response;
import javax.ws.rs.core.Response.Status;
public class HelloWorldResource implements HelloWorldIntf
{
public Response greet() {
return Response.status(Status.OK).
entity("Hi There!!").
build();
}
public Response sayHello(String input) {
Hello hello = new Hello();
hello.setHello("Hello");
hello.setName("Default User");
if(input != null)
hello.setName(input);
return Response.
status(Status.OK).
entity(hello).
build();
}
}
class Hello {
private String hello;
private String name;
public String getHello() { return hello; }
public void setHello(String hello) { this.hello = hello; }
public String getName() { return name; }
public void setName(String name) { this.name = name; }
}