I am using Apache Camel CXF to integrate a SOAP WebService. Everything works fine but I have noticed that my response is coming back as HTTP 202 instead of 200. I am kinda concerned because I know many people hardcode things like if(httpCode == 200) {...} and this could break the current service.
I have tried using different interceptors to override the HTTP code from 202 to 200, but no luck. Also, 202 means Accepted which means the request is in process but not finished. 200 means OK which means the process has finished. Does this means that I am doing something wrong in my route?
What is the right way of fixing this? Interceptor? Setting a Camel headers? Doing something in the route to say it's complete?
I am using Apache Camel 2.12.1 and PAYLOAD mode.
EDIT: It seems something related to OneWay endpoint. Is there any way to deactivate that?
EDIT2: After hours trying things I think I have the root cause. My WSDL is not defining any output for that particular operation. I cannot change the WSDL. That said, I believe that when CXF is using the WSDL for creating the endpoint it automatically assumes it is a OneWay endpoint since there is no output. That means the response is sent back as soon as we get the request with code 202. Also, I believe there is no possible OutInteceptor chain because of this reason. Personally I believe it's ok to send back 202 but it is a service requirement to send back 200. Is there any configuration I change in CXF to set that in OneWay endpoint mode?
Finally, we found an interceptor for doing that:
public class SoapResponseInterceptor extends AbstractSoapInterceptor {
public SoapResponseInterceptor() {
super(Phase.PRE_LOGICAL);
}
#Override
public void handleMessage(SoapMessage message) throws Fault {
message.getExchange().setOneWay(false);
}
}
Hope it helps!
Related
I have an inbound-channel-adapter that forwards message to router and router has one mapping property which calls service activator where I am trying to trigger one REST POST service which accepts input JSON and produce output JSON.
In this case, service activator reutrns null but since http has to return a response.(In inbound-channel-adapter, I am using status-code-expression="T(org.springframework.http.HttpStatus).NO_CONTENT"
I'm using spring-integration v4.3.6
No, it’s possible. Since this component is one-way, there is nothing to return - just only status code header. By default it is 200 OK.
If you would like to return something, you should consider to use HTTP Inbound Gateway instead.
Otherwise your question isn’t clear
I am trying to write a cxf interceptor which will forward all the incoming requests from my app to another app. However for POST requests I am unable to get the body of the request.
The code I am using looks like :
String body = message.getContent(String.class);
However the body comes as null. I looked into cxf code & it looks like you have to specify the exact class (Ex : ArrayList) to get the body. My app has multiple such message classes. I wanted to know if there is a method by which I can avoid writing multiple checks for each of my POJO class & do it in a single if.
You could call message.getContent(InputStream.class) and use CXF IOUtils to read into String. Please refer javatips.net/blog/cxf-interceptor-example for more details
try:
XMLStreamReader body = message.getContent(XMLStreamReader.class);
I am exposing a rest service by using restlet with camel.
I have exposed a rest service as one end, and at another end I have overridden process method.
The code looks like below,
from("restlet:/service/serviceName/{serviceId}?restletMethod=PUT").process(new Processor() {
#Override
public void process(Exchange exchange) throws Exception {
//Implementation goes here.
}
}
I have two issues here.
I am not able to set the content type for the request
I am not able
to achieve versioning of content type
I tried with the following options.
setHeader(Exchange.CONTENT_TYPE, simple("application/json"))
setHeader(Exchange.ACCEPT_CONTENT_TYPE, simple("application/json"))
Still the issue is not solved. Is there any other option?
So your route is a from. This means you send a request to it.
Send a request to it from fiddler, chrome or somewhere else with the headers you want.
Add logging to the route that prints out the entire exchange including the headers. Here you will find Content-Type, and all the other HTTP headers as well.
To access them you need to access the header on the Exchange like any other header.
I don't understand why you are setting headers there.
For example in your process code you can do like this:
String contentType=(String) exchange.getIn().getHeader("Content-Type");
if (contentType.equals("application/json")) {
//do something
}
Note, you need to verify that the header is called Content-Type and not content-type or something similar since RESTLET is case sensitive. That is why you need to add the logging to see the name of the header on the exchange.
I am using a Grizzly HttpServer and i want to add a specific header in every response. Specifically, i want to avoid CORS problems by adding an 'Access-Control-Allow-Origin' header.
So, ideally, i want something like this:
HttpServer server = GrizzlyServerFactory.createHttpServer(uri, crc);
server.setHeader("Access-Control-Allow-Origin" , "*");
Generally, i am looking for a solution that does not require that i have to manually insert this header in every request-response action.
Is there any way to do this?
As #alexey said, there is no way (from the current Grizzly Server version) to do this. If anyone finds something else that works, i will gladly confirm it as an accepted answer.
The best alternative that works quite well is to extend the 'ContainerResponseFilter' class and override the 'filter' method.
Here is an example for 1.x API
Here is an example for 2.x API (minor changes)
I am using dropwizard for writing a webapp and also using Jersey Client as mentioned at
http://dropwizard.codahale.com/manual/client/#man-client-jersey
But it seems that whenever i try to do a post using the jersey client the remote webservice complains that Content-Length header is missing and fails.
public JobResponse createJob(JobRequest job) {
return jerseyClient.resource(URI.create(JOBS_URL))
.type(MediaType.APPLICATION_JSON_TYPE)
.header("Api-Key", job.getApiKey())
.post(JobResponse.class, job);
}
I have confirmed that the request does not contain the header and despite my best efforts I haven't been able to figure out why this is happening. Does anyone know if there is something that I am missing?
PS: The service that i am trying to hit is https://app.zencoder.com/docs/api/jobs/create
This is known "issue" and actually intended behavior.
Problem here is that entity is processed AFTER headers are written out to "the wire", thus Content-Length header value is not know when headers are serialized. If you need to have it, you have several options (with various complexity):
serialize entity by yourself; if you provide entity as string (or byte[]), Content-Length should be set.
create your own MessageBodyWriter, which would compute size of entity in getSize() method call.
there might be some other way how to do it, but I can't think of another right now.. hope it helps.
I was facing the same problem and the answer from Pavel didn't work out for me (I was using a FormMutiPart object).
I was using ApacheHttpClient4 instead of the regular com.sun.jersey.api.client.Client. Changing back to the Jersey Client, the Content-Lenght is calculated (at least in the case of FormMultiPart entity).