[ACCEPTED]-jax-ws change Content-type to Content-Type because server is hyper sensitive-jax-ws

Accepted answer
Score: 16

I have to connect to a poorly implemented 38 server that only understands Content-Type(capital-T) and 37 not Content-type. How can I ask my jax-ws 36 client to send Content-Type?

I've dug this 35 question a bit more and, sadly, I'm afraid 34 the answer is: you can't. Let me share my 33 findings.

First, the code that you'll find 32 in https://jax-ws.dev.java.net/guide/HTTP_headers.html does not give you access to the HTTP headers 31 of the future HTTP request (that hasn't 30 been created at this point), it allows you 29 to set additional HTTP headers for making a request (that will be added to the HTTP 28 request later).

So, don't expect the following 27 code to not return null if you don't put anything 26 before (and actually, you'll only get what 25 you put in there):

((BindingProvider)port).getRequestContext().get(MessageContext.HTTP_REQUEST_HEADERS);

Then, I did a little test 24 based on the code provided in the same link:

AddNumbersImplService service = new AddNumbersImplService();
AddNumbersImpl port = service.getAddNumbersImplPort();

((BindingProvider)port).getRequestContext().put(MessageContext.HTTP_REQUEST_HEADERS,
    Collections.singletonMap("X-Client-Version",Collections.singletonList("1.0-RC")));

port.addNumbers(3, 5);

And 23 this is what I see in the HTTP request when 22 running the client code:

POST /q2372336/addnumbers HTTP/1.1
Content-type: text/xml;charset="utf-8"
X-client-version: 1.0-RC
Soapaction: ""
Accept: text/xml, multipart/related, text/html, image/gif, image/jpeg, *; q=.2, */*; q=.2
User-Agent: JAX-WS RI 2.1.6 in JDK 6
Host: localhost:8080
Connection: keep-alive
Content-Length: 249

Do you notice the 21 difference: only the first char of the X-Client-Version header 20 is kept upper cased, the rest is lowered!

And 19 indeed, if you check the class c.s.x.w.t.Headers that is 18 used to represent HTTP request (and response) headers, you'll 17 see that it "normalizes" keys 16 when they are added (in normalize(String)):

/* Normalize the key by converting to following form.
 * First char upper case, rest lower case.
 * key is presumed to be ASCII 
 */
 private String normalize (String key) {
     ...
 }

So, while the 15 c.s.x.w.t.h.c.HttpTransportPipe class (my understanding is that this is 14 where the HTTP request is created, this 13 is also where previously added headers will 12 be added to the HTTP request headers) actually 11 adds "Content-Type" as key in a c.s.x.w.t.Headers instance, the key will 10 be modified because of the previously mentioned 9 implementation detail.

I may be wrong but 8 I don't see how this could be changed without 7 patching the code. And the odd part is that 6 I don't think that this "normalizing" stuff 5 is really RFCs compliant (didn't check what 4 RFCs say about headers case though). I'm 3 surprised. Actually, you should raise an issue.

So I see 2 three options here (since waiting for a 1 fix might not be an option):

  • Patch the code yourself and rebuild JAX-WS RI (with all the drawbacks of this approach).
  • Try another JAX-WS implementation like CFX for your client.
  • Let the request go through some kind of custom proxy to modify the header on the fly.
Score: 3

You can modify the HTTP headers from the 9 RequestContext. If you have access to the 8 port object you can cast it to a javax.xml.ws.BindingProvider, which 7 will give you access to the RequestContext.

You 6 might also want to remove the unaccepted 5 "Content-type" header.

This page 4 shows how to do it in a bit more detail: https://jax-ws.dev.java.net/guide/HTTP_headers.html

Let 3 me know if you need more code samples, or 2 if you paste some of your code I can show 1 you how to modify it.

More Related questions