Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Howto setup JAX-WS client to use ISO-8859-1 instead of UTF-8?

I would like to configure my JAX-WS client to send messages in ISO-8859-1. Currently UTF-8 is used.

Here is what the client tries to do:

Map<String, Object> reqContext = ((BindingProvider) service).getRequestContext();
Map httpHeaders = new HashMap();
httpHeaders.put("Content-type",Collections.singletonList("text/xml;charset=ISO-8859-1"));
reqContext.put(MessageContext.HTTP_REQUEST_HEADERS, httpHeaders);

But this setting is ignored and tcpmon shows that the following is received by the server:

POST /service/helloWorld?WSDL HTTP/1.1
Content-type: text/xml;charset="utf-8"
Soapaction: "helloWorld"
Accept: text/xml, multipart/related, text/html, image/gif, image/jpeg, *; q=.2, */*; q=.2
User-Agent: Oracle JAX-WS 2.1.5
Host: 1.1.1.1:8001
Connection: keep-alive
Content-Length: 4135

<?xml version='1.0' encoding='UTF-8'?>
<S:Envelopexmlns:S="http://schemas.xmlsoap.org/soap/envelope/">...  

So, the setting is overriden and UTF-8 is used, both in the HTTP header and in the XML message. The service is defined by the WSDL which is encoded in UTF-8.

Q: Should I redefine the service WSDL to be encoded in ISO-8899-1 and then regenerate the client? Or, is it that I am just not setting the HTTP headers properly?

like image 882
Aleš Avatar asked Nov 04 '12 07:11

Aleš


People also ask

How do I convert utf8 to ISO 8859 1?

byte[] utf8 = ... byte[] latin1 = new String(utf8, "UTF-8"). getBytes("ISO-8859-1"); You can exercise more control by using the lower-level Charset APIs. For example, you can raise an exception when an un-encodable character is found, or use a different character for replacement text.

Is ISO 8859 the same as UTF 8?

UTF-8 is a multibyte encoding that can represent any Unicode character. ISO 8859-1 is a single-byte encoding that can represent the first 256 Unicode characters. Both encode ASCII exactly the same way.

What is JAX WS used for?

JAX-WS is a fundamental technology for developing SOAP (Simple Object Access Protocol) and RESTful (Web services that use representational state transfer, or REST, tools) Java Web services, where JAX-WS is designed to take the place of the JAVA-RPC (Remote Procedure Call) interface in Web services and Web-based ...


2 Answers

Using handler:

public class MyMessageHandler implements SOAPHandler<SOAPMessageContext> {

@Override
public boolean handleMessage(SOAPMessageContext context) {
    Boolean outbound = (Boolean) context.get(MessageContext.MESSAGE_OUTBOUND_PROPERTY);
    if (outbound.booleanValue()) {
        try {
            context.getMessage().setProperty(SOAPMessage.CHARACTER_SET_ENCODING,
                            "ISO-8859-1");
        }
        catch (SOAPException e) {
            throw new RuntimeException(e);
        }
    }
    return true;
}

And register the handler:

    BindingProvider bindProv = (BindingProvider) service;
    List<Handler> handlerChain = bindProv.getBinding().getHandlerChain();
    handlerChain.add(new MyMessageHandler ());
like image 122
jaypi Avatar answered Oct 13 '22 00:10

jaypi


The answer from jaypi seems right. But I needed to add some default implementations. Also it was easy to put inline:

UPDATE: I guess you have to set the handlerChain explicitly. changing the result of getHandlerChain will do nothing.

    List<Handler> chain = bindingProvider.getBinding().getHandlerChain();
    chain.add(new SOAPHandler<SOAPMessageContext>() {
      @Override
      public boolean handleMessage(SOAPMessageContext context) {
        LOG.info("BaseService.handleMessage" + context);
        Boolean outbound = (Boolean) context.get(MessageContext.MESSAGE_OUTBOUND_PROPERTY);
        if (outbound.booleanValue()) {
          try {
            context.getMessage().setProperty(SOAPMessage.CHARACTER_SET_ENCODING, "ISO-8859-1");
          } catch (Exception e) {
            throw new RuntimeException(e);
          }
        }
        return true;        
      }

      @Override
      public boolean handleFault(SOAPMessageContext context) {
        return true;
      }

      @Override
      public void close(MessageContext context) {
      }

      @Override
      public Set<QName> getHeaders() {
        return null;
      }      
    });
    bindingProvider.getBinding().setHandlerChain(chain);
like image 36
Nicholas DiPiazza Avatar answered Oct 12 '22 23:10

Nicholas DiPiazza