WebServiceTemplate - difference between Interceptor and Callback? - java

I'm trying to write my first client using Spring-WS and am getting a little confused at some basics. I need to insert a SAML token into the header, and I've noticed that the WebServiceTemplate class allows for both Interceptors and WebServiceMessageCallbacks.
Can someone please help me understand why I should use one versus another?
Secondly, I noticed that the WST class allows for a list of interceptors, but only a single callback. Does anyone know what the logic was behind that design decision? Why is there no ability to pass an array or list of Callbacks?
Thanks,
Eric

I was wondering the same after reading your question (-:
On this link there's a brief explanation and that's exactly how I use both. For instance, for a specific request I need to set the SOAP action:
JAXBElement<Response> response = (JAXBElement<Response>) webserviceTemplate.marshalSendAndReceive(
request,
new SoapActionCallback("PutOrganisationUnitRequest")
);
This is indeed a simple, anonymous class as mentioned in the link. An interceptor on the other hand is defined and used for all requests. Take a look at XwsSecurityInterceptor for instance, I use that to set the authentication on ALL requests.

Related

Skip CXF interceptor for one of the methods in webservices

I have CXF Interceptor that checks field in SOAP header. I want to skip this check for a single method.
Is it possible to do it without parsing soap and checking for method name (for example, annotation).
Thank you!
If you put your interceptor fairly late in the chain (USER_LOGICAL for example), you can grab the BindingOperationInfo object from the exchange to determine which operation was used to process the body. From there, decide wether to look at the SOAP headers or not.
An interceptor gets executed even before CXF has started parsing the xml message (actually I use them to change the xml parser secure factory implementation class :P ), so I think what you need is not supported by the architecture (or at least I am unable to find it, if someone wants to bring some light here I will thank it too).
http://cxf.apache.org/docs/interceptors.html
May you separe your functionality in 2 webservices, each one with different interceptors and validation levels?

How to: Accessing RESTful Web Services with Play Framework 2.1 for Beginners

I am fairly new to many of the concepts and technologies being used in this question so I would appreciate a little understanding and help for a beginner from the community. I am using the Play Framework version 2.1.3 and I need to POST data to a RESTful web service so that it can be inserted into a remote database. An XML response will be returned indicating either success or failure.
I am sure you are aware that the documentation for the Play Framework is quite lacking and is in no way helpful to beginners, therefore I am unsure of how to accomplish this task with best practices in mind. I am looking for a Java solution to this problem, I do not have the time at present to learn the Scala language. My experience with Web Services is fairly limited, normally I would implement a DAO design pattern (or use one of the many available ORM libraries depending on needs) within my application and use JDBC to connect directly to the database. That is not an option here.
My first question would have to be, is there a recommended design pattern for accessing web services? Then, considering the Play MVC framework, how would one best implement such a design pattern, package the data (assuming the application has already captured and validated data from the user), send it off and process the responses back to the user?
I know it is a fairly lengthy question however my intention behind this is to create a knowledge base of sorts for beginners who can easily come in with limited experience, read, understand and replicate what they find here to produce a working solution. Having searched the web quite extensively, I have found a few disjointed snippets but nothing concrete involving these technologies and no up-to-date tutorials. Thank you for your time.
Creating requests is straight-forward. First you provide a URL. There are various methods to add content types, query parameters, timeouts, etc. to the request. Then you choose a request type and optionally add some content to send. Examples:
WSRequestHolder request = WS.url("http://example.com");
request.setQueryParameter("page", "1");
Promise<Response> promise = request.get();
Promise<Response> promise = WS.url("http://example.com").post(content);
The complicated part is to send it and use the response of the request. I assume you have a controller that should return a Result to the user, based on the web service's response. The result is usually a rendered template or maybe just a status code.
Play avoids blocking by using Futures and Promises. The controller's async method takes a Promise<Result> and returns a result (the future value) at some point later. A simple to use promise is provided by the get and post methods shown above. You don't need to care about their implementation, you just need to know that they promise to provide a Response once the request is complete.
Notice the problem here: When creating a request with WS.url("...").get() it will give you a Promise<Response> even though async takes a Promise<Result>. Here you have to implement another promise yourself, which will convert the response to a result using the map method. If you follow the Play documentation, this will look a bit confusing, because Java doesn't has closures (yet) and everything has to be wrapped in a class. You don't have to use anonymous classes inside the method call though. If you prefer more clean code, you also can do it like this:
return async(
request
.get() // returns a `Promise<Response>`
.map(resultFromResponse) // map takes a `Function<Response, Result>` and
// returns the `Promise<Result>` we need
);
The object resultFromResponse may look like follows. It's actually just like a cumbersome definition of some kind of callback method that takes a Response as only argument and returns a Result.
Function<Response, List<T>> resultFromResponse =
new Function<Response /* 1st parameter type */, Result /* return type */>() {
#Override
public Result apply(Response response) {
// example: read some json from the response
String message = response.asJson().get("message");
Result result = ok(message);
return result;
}
};
As #itsjeyd pointed out in the comments, when calling webservices in Play 2.2.x you don't wrap the call in async any more. You simply return the Promise<Result>:
public static Promise<Result> index() {
return request.get().map(resultFromResponse);
}

CXF InFaultInterceptor vs. OutFaultInterceptor

I am working on REST API with CXF framework. Anybody can explain to me more detail about what's different between InFaultInterceptor vs. OutFaultInterceptor? They seems belong to different phase of interceptor. But Do we should put what logic into different Fault Interceptor? I need to abort interceptor chain and response custom response message. I cannot see different on InFaultInterceptor and OutFaultInterceptor for my scenario. What's your typical error handler interceptor? Could you brief introduce your error handling structure of CXF if convenient?
The concept in the interceptor chain is pretty straightforward, in is coming in, out is going out.
For instance, if you want to change the way faults are populated in a SOAP Fault, say to get some variable you are putting in the exception you are throwing, you would use say the Soap12FaultOutInterceptor to modify the fault you are generating. The Soap12FaultInInterceptor would be used to handle incoming faults.
My real question is why do you want to use the interceptor chain, and what is your use case? This is not unusual, but many times unnecessary especially with Spring and aspecting, IMO.

Setting Request Header in java

Is there any way to modify or set-header of request inside action class? I want to modify it or you can say i want to put flag inside request Header just like we put values in 'attribute' and parameters.
You can do this using HttpServletRequestWrapper. But it's quite dirty solution. Are there really no other ways to solve your problem?
You cannot. Request parameters returned from the servlet are unmodifiable Map. You cannot add/delete content returned from request (via servlet).
In order to set a flag, my suggestion is to store it in a session, and on another action, retrieve the flag & delete it from session.
I think you'd need to wrap the original request into a request class containing the change you wish to have.
It might be better design to have the request parameters parsed earlier in processing to such objects that make more sense to your application logic, and then set the state of those objects in the place where you now would like to modify the original header.
The answer to this depends on what problem you're trying to solve.
One of your comments suggests you're trying to test; if this is the case you have two basic options:
Use a mock request (unit-style testing).
Change the header from the client (integration-style testing).
For testing from real clients, set headers on the client side.
For mocking client interactions, you should be using some form of mock. StrutsTestCase, for example, provides MockStrutsTestCase (outside container) and CactusStrutsTestCase (inside container) classes allowing easy manipulation of request properties and characteristics.
If you are trying to open a URL connection using Java,
you can something like this What is the proper way of setting headers in a URLConnection?
If you can make requests with a browser,
You can use this Firefox plugin to add/modify any number of request headers.
https://addons.mozilla.org/en-US/firefox/addon/modify-headers/
Good Luck
You need to give more details. It sounds like you want to manipulate the request header once the server has received the request. I'm not sure I understand why you would want to do that. Modifying the response headers make sense. But not the request.
I think they only clean way you can do this is via an HttpServletRequestWrapper
Just override getHeader, getHeaders, getHeaderNames and you are good to go.

How to specify a parameter as part of every web service call?

Currently, each web service for our application has a user parameter that is added for every method. For example:
#WebService
public interface FooWebService {
#WebMethod
public Foo getFoo(#WebParam(name="alwaysHere",header=true,partName="alwaysHere") String user, #WebParam(name="fooId") Long fooId);
#WebMethod
public Result deletetFoo(#WebParam(name="alwaysHere",header=true,partName="alwaysHere") String user, #WebParam(name="fooId") Long fooId);
// ...
}
There could be twenty methods in a service, each with the first parameter as user. And there could be twenty web services.
We don't actually use the 'user' argument in the implementations - in fact, I don't know why it's there - but I wasn't involved in the design, and the person that put it there had a reason (I hope).
Anyway, I'm trying to straighten out this Big Ball of Mud.
I have already come a long way by wrapping the web services by a Spring proxy, which allows me to do some before-and-after processing in an interceptor (before there were at least 20 lines of copy-pasted boiler plate per method).
I'm wondering if there's some kind of "message header" I can apply to the method or package and that can be accessed by some type of handler or something outside of each web service method.
Thanks in advance for the advice,
LES
Who or what is expecting the user message to be bound to SOAP headers? Are your web services secured? Is that some kind of authentication header? It might have been the original intention. Actually, someone should have the answer to these questions. Find who. And if you find out that you won't ever need it, stop passing it. But if you need it, I think it's better to add it (even if you don't use it for now) unless if modifying the WSDL is not an issue (especially on the client side).
PS: I don't know how to avoid adding a parameter with #WebParam(header=true) to Java methods in order to generate a WSDL with operations having a <soap:header> in their input. AFAIK, this is how JAX-WS works when starting from Java.
If there is no reason why you need to have that variable as a parameter, you can have each one of your services extend a super class. In that super class have spring inject the MessageContext, ServletContext, ServletRequest, HttpHeaders or whichever is appropriate (probably MessageContext for JAXWS) using either the #Context annotation or #Resource annotation.
Then supply some methods in that super class to pull the user information from the request.
If authentication is what you are trying to accomplish you can manipulate contexts from predefined handlers such as protocol or Logical Handlers. E.g. implement SoapHanlder(which is a protocol handler) interface , from there add that class to the handler chain of each service you offer. Very simple and powerful. This gentleman has the best tutorial out there on this topic.

Categories