I receive a SOAP message to a CXF endpoint, with a Long and String value.
eg. [5, 'test']
The camel route receiving messages is already using dataformat=POJO
I need to send these parameters on ActiveMQ to another application.
If I use:
<convertBodyTo type="java.lang.String"/>
The logs show the body contains 5 only. 'test' is not sent.
I tried converting to a POJO before converting to a String, but I can't find proper documentation on making TypeConverters, (seriously, who can read this and figure out actual code from it?)
eg.
<convertBodyTo type="com.company.InfoPojo"/>
<convertBodyTo type="java.lang.String"/>
If I try to just forward the CXF data to the queue without any converting, I get:
Failed to extract body due to: javax.jms.JMSException: Failed to
build body from content. Serializable class not available to broker.
Reason: java.lang.ClassNotFoundException: Forbidden class
org.apache.cxf.message.MessageContentsList! This class is not allowed
to be serialized. Add package with
'org.apache.activemq.SERIALIZABLE_PACKAGES' system property..
Anyone know what the best option here is?
Thanks
You should marshal the parameters to XML or JSON (or any other format that takes your fancy) before sending them to the queue. The consumer will then need to unmarshal them.
No need to mess around with type converters. Camel's data formats make this really easy: https://github.com/apache/camel/blob/master/components/readme.adoc#data-formats
JSON: https://github.com/apache/camel/blob/master/docs/user-manual/en/json.adoc
JAXB: https://github.com/apache/camel/blob/master/components/camel-jaxb/src/main/docs/jaxb-dataformat.adoc
Made a bean and sent to the bean:
public void process(Exchange exchange) throws Exception {
log.info("Converting CXF values for queue.");
Object[] args = exchange.getIn().getBody(Object[].class);
patientKey = String.valueOf((Long)args[0]);
destinationUrl = (String)args[1];
exchange.getOut().setBody(new String(patientKey + "|" + destinationUrl));
}
Related
I am using Apache Camel to access a WebService.
I am trying to inject content into the data I receive from the WebService for testing purposes.
Using getBody(), I only can access the Java objects which were deserialized from the received XML. Does anybody know how I can access the original XML - before deserialization by Camel?
This is my route structure. As you can see, I create a proxy Webservice from bean eaigateway to the real WebService (bean webservice) I am querying.
from("cxf:bean:eaigateway")
.routeId(ROUTE_ID_GATEWAY)
.process(new EnrichBean())
.to(ENDPOINT_WEBSERVICE)
.process(new DisenrichBean())
;
from(ENDPOINT_WEBSERVICE)
.routeId(ROUTE_ID_WEBSERVICE)
.to("cxf:bean:webservice")
;
public class DisenrichBean implements Processor {
#Override
public void process(Exchange exchange) throws Exception {
// This contains the unserialized object returned from the webservice.
// But how to get and set the original XML content?
Object antwort = ((MessageContentsList)(exchange.getIn().getBody())).get(0);
}
}
Original message should be available from:
exchange.getUnitOfWork().getOriginalInMessage()
But in your case it seems like you need Object/XML marshalling.
Some example can be found here: http://camel.apache.org/data-format.html
I want to handle an HTTPs request that a 3rd party is doing towards my system. The requests contains a JSON object
I have tried using the Jetty component of Camel but when the 3rd party performs the requests Camel throws the following exception:
org.apache.camel.RuntimeCamelException: Cannot read request parameters due Invalid parameter, expected to be a pair but was {"id":"321","rec":"533","status":"ok"}
The Jetty endpoint is defined in blueprint as:
<camel:endpoint id="getRequestEndpoint" uri="jetty:{{webServiceProtocol}}://{{jettyIp}}:{{jettyPort}}/getRequest?sslContextParametersRef=sslContextParameters"/>
Am I missing something or are in a totally wrong path?
Make sure that your client is sending the appropriate Content-Type HTTP request header for JSON, which is:
Content-Type: application/json
It looks like it wasn't sent and the Jetty component falls back to form data interpretation.
Make sure you also add expected bean type to your endpoint definition, like this:
.post()
.type(User.class)
.to("direct:your-queue")
This is strictly speaking not an answer, because in this case you get a different exception shown below. But I hope it helps someone.
org.apache.camel.InvalidPayloadException: No body available of type:
com.example.User but has value: {id=69, name=Hello world} of type:
java.util.LinkedHashMap
I'm trying to get a simple queue handler working with the Spring Cloud framework. I've successfully got the message handler polling the queue, However. The problem I'm seeing is that when I post a message to the queue, my handler is failing to unmarshall the payload in to the required java Object.
#MessageMapping("MyMessageQueue")
#SuppressWarnings("UnusedDeclaration")
public void handleCreateListingMessage(#Headers Map<String, String> headers, MyMessage message) {
//do something with the MyMessage object
}
The error I'm getting is
No converter found to convert to class MyMessage
As I understand it, the #MessageMapping should use Jackson to unmarshall my JSON payload into a MyMessage object. However its complaining that it cannot find a converter.
Has anyone come across this?
I'm using the 1.0.0.BUILD-SNAPSHOT version of Spring Cloud.
Jackson is only used if a contentType header is set with value application/json on the SQS message. Otherwise the converters do not know what type of content is contained in the message's payload and the right converter cannot be chosen.
If you use QueueMessagingTemplate#convertAndSend as in the reference application, the contentType header will automatically be set.
I am using spring integration based Component. That components receives some XML and enriched that XML with some more content.
However, if an exception occurs , then i want to sent the received input XML as the failed message, however in current scenario, it will hold the partially enriched XML as there failed Message.
Is there any way through which I can change the failed message of the Exception , which in turn is wrapped by the Messaging Exception.
As it is so specific case, we need to see your configuration and especially where is an error-channel and how you enrich XML.
However, keep in mind, that Message is immutable object and each interaction with it provides a new Message. But the payload is out of scope of the messsaging and it might not be immutable. And if change of some property of your payload and then you get some exception, you end up in the ErrorMessage with inbound message (failed), but payload might change its state.
Looks like it is your case.
You should think about some payload-cloning variant before you start to enrich it.
Here are some advices on the matter: https://jira.springsource.org/browse/INT-2979
I have a Java WebService setup which consumes an xml file and want to be able to produce either xml or json based on what the client requests. I know that this is possible through reading up on Jersey REST methods but it does not show how to extract this information. I have also looked on google all over but can't seem to find any examples of this.
http://wikis.sun.com/display/Jersey/Overview+of+JAX-RS+1.0+Features is the site that I was initially referencing which shows that it is possible, I was just wondering if anyone would be able to help me find out how to actually distinguish the client's request. Is it in the html header? body? And if so what is the proper way to extract it?
This is what my method currently looks like, I do not have any issues with connection, just finding out what the client requests as a return type.
#POST
#Path("getStatisticData")
#Produces ({"application/xml","application/json"})
#Consumes ("application/xml")
public String getStatisticData(#FormParam("xmlCoords") String xmlFile) throws Exception{
Thanks in advance.
You can extract it using the #HeaderParam annotation:
...
public String getStatisticData(#HeaderParam("Accept") String accept,
#FormParam("xmlCoords") String xmlFile) throws Exception {
...
}
The Accept header in the request is used for the client to indicate to the server what methods it supports.
If the client can set HTTP headers, the proper way to do it is to use the Accept header:
http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html
IF this is not possible, the type requested could be passed in as an argument.
Alternatively, expose two different web services: one that returns XML, one that returns JSON. Each web service would call the same code but with a parameter specifying which format to use.