Why is my JAX-WS handler redeclaring the same namespace on every element?

lenavlasovacats

New Member
I've written a JAX-WS handler to add a WS-Security header to my SOAP client's outbound messages:\[code\]package com.soap.client;import javax.xml.namespace.QName;import javax.xml.soap.Name;import javax.xml.soap.SOAPElement;import javax.xml.soap.SOAPException;import javax.xml.soap.SOAPFactory;import javax.xml.ws.handler.MessageContext;import javax.xml.ws.handler.soap.SOAPHandler;import javax.xml.ws.handler.soap.SOAPMessageContext;public class ClientHeaderHandler implements SOAPHandler<SOAPMessageContext> { private static final String WSSECURITY_PREFIX = "wsse"; private static final String WSSECURITY_NAMESPACE = "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd"; private static final String PASSWORD_TEXT_TYPE = "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-username-token-profile-1.0#PasswordText"; /** * {@inheritDoc} * @see javax.xml.ws.handler.Handler#handleMessage(javax.xml.ws.handler.MessageContext) */ @Override public boolean handleMessage(final SOAPMessageContext context) { boolean outbound = false; outbound = (Boolean) context.get (MessageContext.MESSAGE_OUTBOUND_PROPERTY); if (outbound) { try { addSecurityHeader(context); } catch (SOAPException e) { // do nothing } } return true; } private void addSecurityHeader(final SOAPMessageContext context) throws SOAPException { SOAPFactory sf = SOAPFactory.newInstance(); SOAPElement securityElem = sf.createElement("Security", WSSECURITY_PREFIX, WSSECURITY_NAMESPACE); SOAPElement tokenElem = sf.createElement("UsernameToken", WSSECURITY_PREFIX, WSSECURITY_NAMESPACE); SOAPElement usernameElem = sf.createElement("Username", WSSECURITY_PREFIX, WSSECURITY_NAMESPACE); usernameElem.addTextNode("myusername"); tokenElem.addChildElement(usernameElem); Name passwordTypeName = sf.createName("Type", WSSECURITY_PREFIX, WSSECURITY_NAMESPACE); SOAPElement passwordElem = sf.createElement("Password", WSSECURITY_PREFIX, WSSECURITY_NAMESPACE); passwordElem.addAttribute(passwordTypeName, PASSWORD_TEXT_TYPE); passwordElem.addTextNode("mypassword"); tokenElem.addChildElement(passwordElem); securityElem.addChildElement(tokenElem); context.getMessage().getSOAPPart().getEnvelope().addHeader().addChildElement(securityElem); }}\[/code\]This mostly works; however, the WS-Security namespace and prefix are re-declared on each element they are used on (xmlns:wsse=http://...):\[code\]<?xml version='1.0' encoding='UTF-8'?><S:Envelope xmlns:S="http://schemas.xmlsoap.org/soap/envelope/"> <S:Header> <wsse:Security xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd"> <wsse:UsernameToken xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd"> <wsse:Username xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd">myusername</wsse:Username> <wsse:Password wsse:Type="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-username-token-profile-1.0#PasswordText" xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd">mypassword</wsse:Password> </wsse:UsernameToken> </wsse:Security> </S:Header> <S:Body> <MyBody/> </S:Body></S:Envelope>\[/code\]I've tried various combinations of QNames, Names, etc., but I can't seem to make this work. What do I need to change so that the WS-Security namespace is only declared in the topmost Security element?
 
Back
Top