I am using following approaches to create web service client. I could likte to know if connection between client and server is established after creating stub instance like followings.
Otherwise Is connection between client and server established after invoking Remote method calling such as stub.xxxmethod(), myervicePort.xxxMetho()
RPC/Encoded
stub = new MyWsRPCPortStub(new URL(), new MyWsRPCLocator());
stub.setTimeout(pdbTimeout);
Document/Literal
MyServicePort myervicePort = service.getMyServicePort();
After learning the above question I am going to decide when stub instance will be created? I mean there will be two ways:
1- create only one stub instance in application ,I mean I will use singleton pattern
2- create stub instance before invoking a method call each time
What if I use only one stub instance with multithread appiication, each thread open difference sockets at the same time while invoking stub.xxMethod()
At the same time
T1->stub.xxMethod()
T2->stub.xxMethod()
T3->stub.xxMethod()
First of all the approcahes you have mentioned to consume web service in a client do not depend on wether the web service style is RPC or Document Literal. The client is the same for both styles. These styles merely determine how the SOAP message exchanged between client and server is structured. A post to get started on it:-
here.
Messages are sent between the client and server using the SOAP protocol running over HTTP. Hence the communication between client and server should be mainly looked at as a normal HTTP request/response model rather than when and how the connection between them is established and maintained which is the job of underlying TCP protocol; and the API in the web service client and the underlying OS completely abstract away these details for us.
However if you would like to know when a HTTP request is made by a web service client; you can trace it using any of the packet capture tools like 'wireshark' for example.Typically if you have a web service with just one method; there is usually a HTTP GET request made when you use the Service service = Service.create(url, qname) api and a HTTP POST on YourWSInterface.xxxmethod().
About when to create a stub; in a multithreaded environment; if you are going to use the BindingProvider on the client stubs to set data(and not just mere read only calls) before sending to the webservice; yes; you would need some syhcnronization in the client code(with a single instance) or create a pool of client proxies(multiple pooled instances); depending on the requirements of your app.
I hope i have answered the question.
Related
I am using bdd implementation provided by qaf for test automation and using qaf-support-ws for web services testing. I found it very easy to use with all kind of features required for web services test automation with power of TestNG. It helps in easy UI and API orchestration. Our beckend API requires authontication and uses cookie for subsequent API call. I am able to pass coockie by implementation of ClientFilter. I have created providing client by extending RestClientFactory. My client with added Coockie filter works fine with request calls for one domain and whenever I have request on different domain I need to reset client as below:
new RestTestBase().resetClient();
Because of that I have to call API to authenticate each time. If request are for same domain I don't need to reset client. Is there any other better way to manage cookies? So that I can work with multiple domain without resetting client.
Another simpler way is by using Apache HTTP client as below:
protected Client createClient() {
HttpClient httpClient = new HttpClient();
ApacheHttpClientConfig config = new DefaultApacheHttpClientConfig();
config.getProperties().put(ApacheHttpClientConfig.PROPERTY_HANDLE_COOKIES, true);
// ApacheHttpClient httpClient = ApacheHttpClient.create(config);
ApacheHttpClientHandler clientHandler = new ApacheHttpClientHandler(httpClient, config);
ClientHandler root = new ApacheHttpClient(clientHandler);
Client client = new Client(root, config);
return client;
}
with this implementation you will not required to reset client when doing request for another domain and wise-versa. Complete example can be found here.
I am very much confused about the concept behind the QName.
lets take for example (I have taken these examples from http://www.mkyong.com/):
ServerInfoService sis = new ServerInfoService();
ServerInfo si = sis.getServerInfoPort();
System.out.println(si.getServerName());
And with QName :
URL url = new URL("http://localhost:8888/ws/image?wsdl");
QName qname = new QName("http://ws.mkyong.com/", "ImageServerImplService");
Service service = Service.create(url, qname);
ImageServer imageServer = service.getPort(ImageServer.class);
Now my question is :
1) Is there any concepts based on which we have to decide which type of client we can write
2) What is the purpose or additional benefits in using QName because all I can see here is that it increases complexity as compared to simple client.
Here is what i know:-
It depends on how you would want to make use of your client to invoke the web service.
The first approach
ServerInfoService sis = new ServerInfoService();
ServerInfo si = sis.getServerInfoPort();
is the plain simple proxy generation approach; where-in you use a tool like wsimport to generate proxies/stubs to your SEI(Service Endpoint Interface)/web-service interfaces and invoke methods on it like any other java method call. Is mostly used in clients where you simply need to invoke methods on the web-service without getting into granular details.
The QName or rather the Service approach offer finer controls over how the client and webservice communicate. JAXWS 2.0 introduced something called as a Provider interface which was an alternative to your SEI which basically let a client communicate at the XML message level and provide a dynamic representation/view of your web-service to the client. More here. The primary use of Service API is mostly to create Dispatch instances which basically let a client dispatch to a speicific port(method qualified using QName api) using JAXB messages as XML payloads.
Other uses of Service api let a client call methods on the webservice asynchronously; provide access to handlers; etc. A good example of using the Service and QName approach to help you understand further and to relate to what i have said is this link here:- Dispatching Web Service Calls.
This being said there is a lot more to know and understand; but hope this gives you a start.
I need to implement RPC over STOMP, where the client runs with javascript in a browser, and the server side is implemented using Spring messaging capabilities.
While using #MessageMapping is fine for normal messaging, I find using #SendToUser quite limitating for implementing RPC because the client has an hard time to understand which reply is associated with which request in a scenario when multiple simultaneous requests are being made from the client.
Of course there is no problem when just only one request is made, and the client waits for its reply, but problems arise when the client has to keep track of multiple "open" rpc calls.
I've managed to make the system mostly fine by associating an ID with every request, i.e.: the client sends an id together with the message, and the server replies with a special message wrapper that contains this id, so the client is able to associate asynchronous replies with requests.
This works fine but has several limitations:
I have to develop code that needs to understand this structure, and that defies the uitlity to have simple annotated methods
when the server side code generates an Exception the Spring #MessageExceptionHandler get called and the correct Exception is returned to the client, but the request id is lost because the handler has no (easy) way to access it.
I know that with rabbitmq we can add "reply-to" header to every request that needs to be associated with a special reply (the rpc response), and this is implemented by creating a special temporary queue that the user is automatically subscribed to, but how may I use this scheme in Spring? Also, that would tie me a specific broker.
How may I elegantly implement a correct RPC call in Spring that correctly handles server side exceptions?
I find this a general problem and I think Spring could benefit greatly to implement it natively.
This not exactly what you demand, but maybe you can attempt something like this :
Path variables in Spring WebSockets #SendTo mapping
You define an ID on your client and send id to the queue /user/queue/{myid}
On the serveur side you will have a class who looks like this :
#MessageMapping("/user/queue/{myid}")
public void simple(#DestinationVariable String id, Object requestDto) {
simpMessagingTemplate.convertAndSendToUser(userId, "/user/queue/" + id, responseDto);
}
This solution can work with the same principle as the rabbit mq solution you mention.
Hope this helps.
If you do not need the exception/reason on the client, but only want to know which message failed you could send ack messages for successful messages. For successful messages you always have easy access to the message id / headers. By the absence of the ack message the client knows which message has failed.
Of course this comes at the costs of sending all the ack messages and knowing the timout of requests. Also additional code is required to keep track on the client side, but this can be done using a middleware and would end up in an ok-ish dev experience for the business logic.
I need to create the dynamic client to call web services, which can call web services with Service Mode as Service.Mode.PAYLOAD as well as Service.Mode.MESSAGE. I have created the Dispatcher as:
Dispatch<Source> sourceDispatch =service.createDispatch(portName, Source.class, Service.Mode.PAYLOAD);
But this can invoke the services with Service Mode PAYLOAD only. Please suggest me the way how can I previously determine the Service Mode from WSDL link (service Mode parser code) before creating Dispatch instance?
The mode does not depend on the WSDL.
If you want to pass to sourceDispatch.invoke(T msg) an entire SOAP message use mode.MESSAGE. If you only want to pass the PAYLOAD (the body) use mode.PAYLOAD, and invoke will wrap it in a message for you.
The mode also determines wether invoke returns you a message or the payload.
I am new to android programming. I writing a client server program. I want to create ServerService which listen for incoming connections, once request comes from the client it creates two other services SendService and ReceiveService to write and read from the socket in two different threads. Hence I derived these services from IntentService. How to pass socket information to SendService and ReceiveService? Can I have a simple member variable in these two services and set it from ServerService? If so how to set this value? Using getBaseContext()?
A service is just a class that extends Service, you can have the same tool set as any class. So your answer is yes, and you assign it via your preferred method.