Are there any resources / libraries I should look into if trying to implement client and server side components for a SOAP web service in Java (defined in WSDL) but not wishing to use the WSDL/JAXB-based code generation for client and server stubs?
For the record, the reason I am trying to eschew wsimport for stub generation is that both wsimport and xjc fail to properly generate Java code for the schema files I have to use - which are numerous and rather complex - and despite using episodic compilation I still hit what may likely be bugs in JAXB code generation logic (e.g. see here and here) and overall I have the impression that this technology is not very solid, when it comes to complex schemas.
So, are there any resources or libraries I should look into to help be build SOAP services by writing and reading XML content directly on the HTTP connection? Currently I am just calling write on a java.net.URLConnection like:
URLConnection connection = url.openConnection();
connection.setDoOutput(true); // Triggers POST.
connection.setRequestProperty("Accept" , "text/xml, multipart/related");
connection.setRequestProperty("Content-Type" , "text/xml; charset=utf-8");
connection.setRequestProperty("Host" , url.getHost());
connection.setRequestProperty("Proxy-Connection", "keep-alive");
connection.setRequestProperty("Content-Length" , String.valueOf(postContent.length()));
OutputStream output = connection.getOutputStream();
output.write(postContent.getBytes("UTF-8"));
If you need something "low level" (but not as extreme as writing the messages as strings) have a look at SAAJ.
Reference implementation is here and you can find a starting tutorial in The Java EE 5 Tutorial.
Related
We are in process of migraring from Jersey 1 to 2. As part of this, I am trying to move caching configurations in Jersey 1.
With Jersey 1, we were using ApacheHttpClient4 which internally was using a ApacheHttpClient4Handler built using CachingHttpClient.
ApacheHttpClient4Handler httpClientHandler = new ApacheHttpClient4Handler(cachingHttpClient, null, false);
javax.ws.rs.client.Client client = new ApacheHttpClient4(httpClientHandler, clientConfig);
But looks like ApacheHttpClient4Handler is not available in Jersey 2.
Question here is, is there an alternative to ApacheHttpClient4Handler available?
I know how caching works as a server (Setting response headers etc). My question here is executing the external cacheable REST requests which my Jersey Client can cache.
Long term goal is to move away with Jersey comletely and use something like RestTemplate. But for now I am trying for a short term solution.
Any help here will be much appreciated.
Thank you for your assistance.
Question:
Why does my REST service seem to perform so poorly using rest interfaces in dlang vibe.d when compared to creating request handlers manually?
More Information:
I have been prototyping a RESTful service using the vibe.d library in dlang. I'm running a test where a client sends GET and POST requests to the server with a payload of some given size, say 2048 byte (i.e. the GET response would have 2k, the POST request would have 2k).
I'm using the "registerRestInterface" and "RestInterfaceClient" API in the vibe.d library to create my server and client sort of like this...
Server:
auto routes = new URLRouter;
registerRestInterface(routes, new ArtifactArchive());
auto settings = new HTTPServerSettings();
settings.port = port;
settings.bindAddresses = [host];
settings.options |= HTTPServerOption.distribute;
listenHTTP(settings, routes);
runEventLoop();
Client:
IArtifactArchive archive = new RestInterfaceClient!IArtifactArchive(endpoint)
IArtifactArchive.Payload result;
result = archive.getContents(info.FileDescriptor, offset, info.BlockSize);
I'm not doing anything fancy in my interface. Just filling a byte array and passing it along. I know performance depends on many different things; however I seem to see about 160kB transfer rate when using REST interfaces in vibe.d and roughly 5MB transfer rate when using manual http request handlers like this:
void ManualHandleRequest(HTTPServerRequest req, HTTPServerResponse res) ...
listenHTTP(settings, &ManualHandleRequest);
I really like the REST interface API, but I can't suffer that kind of performance loss in order to use it. Any thoughts on why it seems so much slower than the other method? Perhaps I'm configuring something wrong or missing something. I am somewhat new to the D programming language and the vibe.d library.
Thank you for your time!
I suspect that with custom request handler you actually write response as a byte array. REST interface generator serializes all return data into JSON by default which creates huge overhead compared to raw array.
This is just a random guess though, I need to see actual REST method implementation to say for sure and/or propose solution.
I'm using GWT RPC Calls for Server Side Request so far and it's pretty good. I'm planning on separating my Code into Servlets and GWT Client Side. Since i'm using RPC calls, it seems impossible. The Reason i want to do like this is , i'm planning to provide white labeling option for my App. So if i could separate the code to client code and servlets, i can simply provide the White Labeled client code to my Partners to host on their server. I have checked with GWT RequestBuilder and Access-Control Allow-Origin : Origin from Client Header and it works fine.
However i need to implement gwt-serialization over RequestBuilder request and Servlet Responses. How can i do this ..?
Scenario I like to make:
RequestBuilder sending Serializable String(Which is a IsSerialiazible object) to Servlet.
Servlet deserializes the String to Java Object,Processes and Returns the String Response of a 'IsSerialiazable' Object.
The Response String recieved in GWT RequestBuilder deserialzes it back to a Java Object(JS after Compiling).
I have checked on RemoteServiceServlet class which seems to have some info on serializing and deserializing request and response. But i couldn't get it right to get it to work with RequestBuilder. Any ideas , Hope it will be helpful for everyone.
public final void processPost(HttpServletRequest request,HttpServletResponse response)
throws IOException, ServletException,SerializationException
{
// Read the request fully.
//
String requestPayload = readContent(request);
// Let subclasses see the serialized request.
//
onBeforeRequestDeserialized(requestPayload);
// Invoke the core dispatching logic, which returns the serialized
// result.
//
String responsePayload = processCall(requestPayload);
// Let subclasses see the serialized response.
//
onAfterResponseSerialized(responsePayload);
// Write the response.
//
writeResponse(request, response, responsePayload);
}
GWT RPC and RequestBuilder serve different purposes. We cannot mix/match them.
GWT RPC - Services which fetch Data
GWT Request Builder - fire requests for static resources like js,css, json objects, querying soap services etc
The only feasible solution at the top of my mind for your approach of servicing requests is by using JSON - https://developers.google.com/web-toolkit/doc/latest/tutorial/JSON
You can keep your servlets code as is and then use RequestBuilder to query URL mapped to these servlets for JSON objects. Process the JSON objects using JSNI or Overlay concepts.
I'm trying to get the GWT Serialization & Deserialization source.Unfortunately, i have been stuck with other works and couldn't look on this right now. When i get the GWT Serialization Classes , i will update.
For a web service call using a WSDL, I'm getting the error Cannot find dispatch method for {http://ws.somecompany.com/services}ValidateUser, what does that mean exactly? Does it mean that it cannot find ValidateUser?
This typically means that the SOAP framework could not find the operation that should be invoked via this request. A SOAP framework typically inspects the message to find pointers about how to route the message to the operation. Reasons for this error are mostly configuration issues (different namespaces, different encodings (RPC vs. doc/lit), usage of WS-Addressing vs. plain SOAP etc.)
I had a similar problem and struggling, googling for 1 day. But it was a simple mistake that instead of:
{http://ws.somecompany.com/services}ValidateUser
It should be
{http://ws.somecompany.com/services/}ValidateUser
I had not checked my WSDL clearly.
In my case I solved by making sure that my config file either app.config or web.config depending on your client has correct endpoint. I had wrong address in my endpoint. I changed it and it worked fine.
I also lost a day to this issue, albeit with a different root cause.
In our case, two similar endpoint urls had got mixed up in the properties file. Both services were present and running, but the WSDLs didn't match up, so instead of a ConnectionException, we were getting this SOAPFaultException: "Cannot find dispatch method".
My fifty cent, I got same error message but my case was yet different from all above, so hopefuly it might help someone.
I had .wsdl file, which got outdated without my knowledge when colleagues on the other side of ws renamed some element. Unfortunately, change was not visible when I compared .wsdl with theirs because .wsdl file had .xsd import which actually contained renamed element. After I found change, I updated my .xsd file and tada! error is gone and it worked.
In my case, the following exception was throwing even I've supplied all the parameters
SoapFault exception: [S:Client] Cannot find dispatch method for {}parameters in
After banging my head few hours, just adding a \ while initializing SoapClient solved the problem.
From:
$client = new SoapClient($soapURL);
To:
$client = new \SoapClient($soapURL);
I had the same issue in my .NET Application, In my case setting url same as "http://x-xxx-xx-xx-01:8080//TestProject/testproject?wsdl" (dummy url) solved the problem in the below code.
Vb.Net
Dim rptGen as WSTestProject.testproject = Nothing
rptGen = New WSTestProject.testproject With {
.Url = "http://x-xxx-xx-xx-01:8080//TestProject/testproject?wsdl",
.Timeout = 1200000
}
Here, WSTestProject is the WebService NameSpace and testproject is the web method.
I am using a feign client for soap and I had the similar issue,Adding the correct namespace to the JAXB request and response object resolve the issue.
The issue was in my environment was the wsdl cache in php. The updated wsdl was not picked by the client and it was referring to the old wsdl.
You can do either one of the following options when you do the development of the web service and test, as the wsdl change during the update/implementation of the web service
Add WSDL_CACHE_NONE to soap client creation
$myServices_client = new SoapClient($myServices_wsdl_URL, array('cache_wsdl' => WSDL_CACHE_NONE) );
Set initialization parameter
ini_set("soap.wsdl_cache_enabled", 0);
Adding '/' will work for you.
Error: Cannot find dispatch method for {http://zzz.com}servicename
Not Working Request: xmlns:ser='http://zzz.com'>
Working Request: xmlns:ser='http://zzz.com/'>
I picked up an old Java project. I am not sure how it worked before, but I saw similar error and the reason was in wrong SOAP HTTP endpoint binding at server side.
Doesn't work:
Endpoint.create(HTTPBinding.HTTP_BINDING, servicePortType);
Works:
Endpoint.create(SOAPBinding.SOAP11HTTP_BINDING, servicePortType);
I am trying to invoke a WebService through SOAP using Erlang and YAWS (yaws_soap_lib module specifically). The examples published on http://yaws.hyber.org/soap_intro.yaws work for me.
However, when trying to invoke my own web service YAWS fails. The first problem were partner links in the WSDL that were put there because of BPEL is befind this service. I deleted them (for now).
Unfortunately, I've come across another problem: mentioned WSDL has an empty <types> tag. Now, I am not very familiar with WSDL specification and SOAP so my question is whether it is
Erlang SOAP library issue that cannot handle empty <types> tag or
badly generated WSDL?
Does anyone know any better Erlang library for handling SOAP? I have taken a look at erlsoap but it does not support WSDLs.
EDIT: error caused by mentioned WSDL:
::error:function_clause
in function erlsom_add:add_model/2
called as add_model({model,[{type,'_document',sequence,
[{el,[{alt,'soap:Envelope','soap:Envelope',...},
{alt,'soap:Header',...},
{alt,...},
{...}],
1,1,1}],
[],undefined,undefined,1,1,1,false,...},
{type,'soap:detail',sequence,
[{el,[{alt,'#any',...},{alt,...},{...}|...],0,unbound,1}],
[],
{anyAttr,"lax","##any",[...]},
undefined,2,1,1,...},
{type,'soap:Fault',sequence,
[{el,[{alt,...}],1,1,...},
{el,[{...}],1,...},
{el,[...],...},
{el,...}],
[],undefined,undefined,5,1,...},
{type,'soap:Body',sequence,
[{el,[{...}|...],0,...}],
[],
{anyAttr,[...],...},
undefined,2,...},
{type,'soap:Header',sequence,
[{el,[...],...}],
[],
{anyAttr,...},
undefined,...},
{type,'soap:Envelope',sequence,[{el,...},{...}|...],[],{...},...}],
[{ns,"http://schemas.xmlsoap.org/soap/envelope/","soap"},
{ns,"http://www.w3.org/2001/XMLSchema","xsd"}],
"http://schemas.xmlsoap.org/soap/envelope/",[]},undefined)
in call from yaws_soap_lib:initModel2/5
For those who are familiar with the source code: The problem is the Xsds array returned by getXsdsFromWsdl function is empty.
My XML schema fu is a bit rusty, but as far as I can see the schema permits empty <types/> elements. That would suggest the first alternative, though it's hard to be sure. What error message do you get?
I would guess given the function clause error that erlsom is not handling some particular function input as being undefined. But I assume you've already validated your WSDL to make sure it's OK? Also, any chance of posting the WSDL somewhere so we can see it?
The issue has been resolved in latest YAWS version. In order to construct mentioned WSDL model following command has to be invoked:
yaws_soap_lib:initModel(WSDL_FILE_URL, [{include_fun, {erlsom_lib, find_xsd}}])