getHeaders method from SoapHandler interface - java

Could you please explain what exactly the method getHeaders from SOAPHandler interface is supposed to do?
http://docs.oracle.com/javaee/5/api/javax/xml/ws/handler/soap/SOAPHandler.html#getHeaders%28%29
I'm not sure if it creates additional headers or if it should just tell the runtime which headers the message should have.
I've been sweeping the internet looking for detailed information but I couldn't find any. I think is is so basic and obvious that no documentation is needed LOL :-)
Thanks

The description you're looking for can be found in the JAX-WS 2.2 spec in the section titled, "10.2.1 SOAP mustUnderstand Processing". Inbound messages require an additional processing step that occurs before the start of normal handler processing. Basically, the set of QName instances returned from getHeaders allows the handler to contribute to the full set of SOAP headers that a node understands (the other contributors to the full set are documented in the spec). If an inbound SOAP header contains the mustUnderstand attribute with a value of 1 or true, then an exception will be generated if that header can't be marked as understood.

EDIT: Apparently I was wrong and after reading further I must agree, therefore please ignore this.
A SOAP message is a HTTP request. HTTP requests can have number of different headers as a part of the message (e.g. in SOAP 1.1 there was a header called SOAPAction, which could contain the name of the service and operation). The getHeaders function returns the list of all the headers QNames that came with the request, so in case of previous example, you would get a list that would contain element of value "SOAPAction".

Related

Is it possible to include a request body in a GET request using Spring WebClient?

I know sending a body with a GET request isn't the best idea but I'm trying to consume an existing API which requires it.
Sending a body with POST is straight-forward:
webClient.post()
.uri("/employees")
.body(Mono.just(empl), Employee.class)
.retrieve()
.bodyToMono(Employee.class);
It won't work with webClient.get() though, because while the post() method returns a WebClient.RequestBodyUriSpec, the get() method returns WebClient.RequestHeadersUriSpec<?>, which doesn't seem to allow any body definitions.
I've found a workaround for Spring RestTemplate here: RestTemplate get with body,
but had no luck finding any for the new WebClient.
While the other responses are correct that you shouldn't use a body with a GET request, that is not helpful when you do not own, or cannot change the already existing method you are calling.
The problems is WebClient#get returns a WebClient.RequestHeadersUriSpec which does not provide a way for us to set the body.
WebClient#post returns a WebClient.RequestBodyUriSpec which does provide us a way to set the body but will cause us to use the wrong HTTP method, POST instead of GET.
Thankfully for us stuck in this situation there is WebClient#method which returns a WebClient.RequestBodyUriSpec and allows us to set the HTTP method.
webClient.method(HttpMethod.GET)
.uri("/employees")
.body(Mono.just(empl), Employee.class)
.retrieve()
.bodyToMono(Employee.class);
You may still run into issues in your testing libraries though...
A GET reques has no body. It is forbidden (well, not forbidden, but not used at all) by the HTTP specification. You have two approaches here:
Do a POST. It is there just for that.
Use a query string and pass the data in that part of the URL.
Of course, you can attach the needed fields and pass a payload to the GET request, but it will probably be ignored, or worse, identified as an error and rejected by the server, before your served code has access to it. But if you are passing data to the server to do some processing with it, then POST is what you need to use.
Extracted from RFC-7231. HTTP 1.1. Semantics and code:
A payload within a GET request message has no defined semantics;
sending a payload body on a GET request might cause some existing
implementations to reject the request.
(markup is mine)
Reasons for this are, mainly, that a GET method must be idempotent, producing the same output for the same URL, if repeated. POST doesn't have these requirements, so POST is your friend.

Multiple content-types for request in webservice

I have one webservice which can take multiple content-types in request
text/plain
application/json
Now, client can send any of them either json or text.
I have two options available on server
I can create separate apis for different content types
I can parse request data and check if its json or text?
What is better approach here?Is there a design pattern suited for this need?
Note: Management prefer to have one api which can support multiple content-types.
The client must include a Content-Type header indicating the format of the entity they are sending to the server. If the server does not support the format which a client has sent, the expected response is 415 Unsupported Media Type.
I would go with option 1 and have the common logic placed in a seperate method. That way you let the API check and parse the input data for you.
In http you use the "accept"- header to define what type you expect the response to be. The server delivers the content as defined in accept header, the default if it's not set or 406 - "Not acceptable" if the type is not supported
https://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html
One way would be to use #Path annotations more thoroughly-
The #javax.ws.rs.Path annotation must exist on either the class and/or a resource method. If it exists on both the class and method, the relative path to the resource method is a concatenation of the class and method.
See this link https://docs.jboss.org/resteasy/docs/1.1.GA/userguide/html/Using__Path_and__GET___POST__etc..html

How to determine a correct request method is executed in RESTful webservice?

I want to understand how a RESTful web service identifies if a correct request method is called.
For example,
I have a REST service it exposes one operation which is of type GET.
Assume a REST client has invoked the operation using a wrong request method(PUT).
In this scenario, how the service/framework identifies a correct request method is invoked?
I have gone through various posts to understand the scenario but I don't find any information.
Please let me know your comments.
The first line sent in an HTTP request looks like this:
GET /index.html HTTP/1.1
The HTTP request thus contains the HTTP method (POST, PUT, GET, etc.). The framework reads this method, and invokes the Java method that is mapped (thanks to annotations, or XML configuration, or whatever) to the URL (also contained in the HTTP request, as shown above) and the HTTP method. If none is found, then an error response is sent back (405 Method Not Allowed, if the resource is found, but with another method, or 404 if the resource is not found).
It's the http protocol not REST that checks headers, and reports back with an error code.
REST is sort of a strategy, not an implementation.
Hope this helps.

JAX-RS/Jersey response 406 with no entity but RFC 2616 recommends one

I am working in Java Web Service with Jersey. I'd like to understand how could handle the following problem:
Apparently, JAX-RS (JSR 311) for every situation with 406 Status, say that response will have no entity. For example, in section 3.7.2 Request Matching, Identify the method that will handle the request:
At least one of the acceptable response entity body media types is a supported output data
format (see section 3.5). If no methods support one of the acceptable response entity body
media types an implementation MUST generate a WebApplicationException with a
not acceptable response (HTTP 406 status) and no entity. The exception MUST be processed as described in section 3.3.4.
However, RFC 2616 recommends another thing:
10.4.7 406 Not Acceptable
The resource identified by the request is only capable of generating response entities which have content characteristics not acceptable according to the accept headers sent in the request.
Unless it was a HEAD request, the response SHOULD include an entity containing a list of available entity characteristics and location(s) from which the user or user agent can choose the one most appropriate. The entity format is specified by the media type given in the Content-Type header field. Depending upon the format and the capabilities of the user agent, selection of the most appropriate choice MAY be performed automatically. However, this specification does not define any standard for such automatic selection.
Note: HTTP/1.1 servers are allowed to return responses which are
not acceptable according to the accept headers sent in the
request. In some cases, this may even be preferable to sending a
406 response. User agents are encouraged to inspect the headers of
an incoming response to determine if it is acceptable.
So, what should I do for Jersey include an entity containing a list of available entity characteristics in 406 scenario.
Answer my own question...
I open a ticket in Jersey project to solve this issue. Jersey community promptly answered me that Java Spec to Webservice was already wrong. A new ticket should be opened in JAX project (Java Spec to Web Services) to in a future Jersey implement the right behavior.
https://java.net/jira/browse/JAX_RS_SPEC-363
However, checking JAX project you can find 63 unassigned tickets (100%).
https://java.net/jira/browse/JAX_RS_SPEC/fixforversion/14716
"So what?"
The last activity in this Jira was in Nov 2013. Last ticket opened was in May 2013. The first was in Jan 2009. Hardly there will be any change for this issue in the near future.

Empty soap action when SAP Solution Manager call WCF Webservice

Context :
SAP Solution Manager (will call it SolMan) exposes a SOAP webservice where a 3rd party can call to interoperate with it. The 3rd party application can also implement the same webservice interface so that SolMan can interoperate in the other direction.
I need to interoperate with SolMan in both directions. My webservice is a WCF Service based on the interface and the types generated from the WSDL of the SolMan webservice with VS2010 "Add Service reference".
Problem #1
In the WSDL, all of the declared operations has soapAction="". When the service contract interface has been generated from VS2010, all OperationContractAttribute are Action="", ReplyAction="*". Since more than one OperationContract has the same Action (empty string), the Webservice doesn't work, the exception is :
[InvalidOperationException: The operations AcceptIncidentProcessing
and AddInfo have the same action (). Every operation must have a
unique action value.]
Is this normal? There is another way to fix it other than removing all Action="" declarations from the generated ServiceContract interface?
Problem #2
I've removed all empty string Actions from the generated ServiceContract interface.
I can now inspect the WSDL generated by my webservice and call it with my .net wcf client.
SolMan is unable to call my webservice, after enabling MessageLogging in my web.config, I found that my service has faulted with :
<s:Fault>
<faultcode xmlns:a="http://schemas.microsoft.com/ws/2005/05/addressing/none" xmlns="">a:ActionNotSupported</faultcode>
<faultstring xml:lang="en-CA" xmlns="">The message with Action '' cannot be processed at the receiver, due to a ContractFilter mismatch at the EndpointDispatcher. This may be because of either a contract mismatch (mismatched Actions between sender and receiver) or a binding/security mismatch between the sender and the receiver. Check that sender and receiver have the same contract and the same binding (including security requirements, e.g. Message, Transport, None).</faultstring>
</s:Fault>
Indeed inspecting the SOAP request message shows that soapaction is present in the HTTP Headers, but empty, and that Action is also presents in the SOAP headers and it is also empty .
So I found a Post about the Microsoft's 1DispatchByBodyBehavior1 sample, gave it a try and replayed the http request with Fiddler wihout success. The only way I manage to make it work, is by removing the <Action> and <To> from the SOAP headers in Fiddler. SolMan will indeed continue to pass these headers.
Is it valid that SolMan sets no Action when calling a SOAP webservice?
What am I doing wrong?

Categories

Resources