Как добавить заголовок мыла при выполнении запроса на мыло с использованием объектов Java, сгенерированных wsdl

Я создал клиентские Java-объекты, используя JAX-WS RI. Я пытаюсь сделать SOAP-запрос к веб-службе. Сервис требует аутентификации в заголовке, который выглядит следующим образом:

<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/">
<soapenv:Header>
<xsd:authHeader>
<xsd:user>[email protected]</xsd:user>
<xsd:password>password1</xsd:password>
</xsd:authHeader>
</soapenv:Header>
<soapenv:Body>
<ns:searchAssetsParam>
<ns:includeSubfolders>true</ns:includeSubfolders>
<ns:resultsPage>2</ns:resultsPage>
</ns:searchAssetsParam>
</soapenv:Body>
</soapenv:Envelope>

Сгенерированные объекты Java имеют методы для вызова службы, создания объектов и построения заголовка. Но у меня возникли проблемы с настройкой заголовка во время вызова.

Вот код, который я использую:

IpsApiService service = new IpsApiService();
IpsApiPortType port = service.getIpsApiSoapPort();
SearchAssetsParam searchAssetsParam = buildSearchAssetsParam();
SearchAssetsReturn response = port.searchAssets(searchAssetsParam);

buildSearchAssetsParam() создает объект запроса. Я создал объект заголовка следующим образом:

AuthHeader header = new AuthHeader();
header.setUser("[email protected]");
header.setPassword("password1");

Как мне установить этот AuthHeader для запроса на обслуживание?

Спасибо, Вену


person Venu Doddi    schedule 14.08.2012    source источник


Ответы (4)


Однажды у меня была такая же проблема. Мне нужно было изменить заголовок SOAP веб-службы JAX-WS при каждом запросе. Чтобы решить эту проблему, я создал обработчик следующим образом:

public class MyHandler implements SOAPHandler<SOAPMessageContext> {

    private static final Logger LOGGER = LoggerFactory.getLogger(MyHandler.class);

    private String username;

    private String password;

    @Override
    public boolean handleMessage(SOAPMessageContext context) {
        try {
            SOAPMessage message = context.getMessage();
            SOAPHeader header = message.getSOAPHeader();
            SOAPEnvelope envelope = message.getSOAPPart().getEnvelope();
            if (header == null) {
                header = envelope.addHeader();
            }
            QName qNameUserCredentials = new QName("https://your.target.namespace/", "UserCredentials");
            SOAPHeaderElement userCredentials = header.addHeaderElement(qNameUserCredentials);

            QName qNameUsername = new QName("https://your.target.namespace/", "Username");
            SOAPHeaderElement username = header.addHeaderElement(qNameUsername );
            username.addTextNode(this.username);
            QName qNamePassword = new QName("https://your.target.namespace/", "Password");
            SOAPHeaderElement password = header.addHeaderElement(qNamePassword);
            password.addTextNode(this.password);

            userCredentials.addChildElement(username);
            userCredentials.addChildElement(password);

            message.saveChanges();
            //TODO: remove this writer when the testing is finished
            StringWriter writer = new StringWriter();
            message.writeTo(new StringOutputStream(writer));
            LOGGER.debug("SOAP message: \n" + writer.toString());
        } catch (SOAPException e) {
            LOGGER.error("Error occurred while adding credentials to SOAP header.", e);
        } catch (IOException e) {
            LOGGER.error("Error occurred while writing message to output stream.", e);
        }
        return true;
    }

    //TODO: remove this class after testing is finished
    private static class StringOutputStream extends OutputStream {

        private StringWriter writer;

        public StringOutputStream(StringWriter writer) {
            this.writer = writer;
        }

        @Override
        public void write(int b) throws IOException {
            writer.write(b);
        }
    }

    @Override
    public boolean handleFault(SOAPMessageContext context) {
        LOGGER.debug("handleFault has been invoked.");
        return true;
    }

    @Override
    public void close(MessageContext context) {
        LOGGER.debug("close has been invoked.");
    }

    @Override
    public Set<QName> getHeaders() {
        LOGGER.debug("getHeaders has been invoked.");
        return null;
    }

    public void setUsername(String username) {
        this.username = username;
    }

    public void setPassword(String password) {
        this.password = password;
    }
}

Он добавляет необходимые параметры в мой заголовок SOAP и вызывается при каждом запросе. Все, что вам нужно сделать, это изменить метод handleMessage в соответствии с вашими потребностями.

person Paulius Matulionis    schedule 03.10.2012
comment
я создал заглушку с помощью Axis2, так как я могу добавить это, я также сталкиваюсь с той же проблемой - person Rangappa Tungal; 03.12.2012
comment
Большое спасибо за ответ, спас мои драгоценные дни :) - person Kumaran; 17.09.2014

У меня это работает, переопределяя метод public void setAttribute(String namespace, String localName, String value).

import javax.xml.namespace.QName;
import org.apache.axis.Constants;
import org.apache.axis.message.SOAPHeaderElement;

@SuppressWarnings("serial")
public class ADESHeaderElement  extends SOAPHeaderElement 
{

     public ADESHeaderElement(QName qname, Object value)
        {
            super(qname, value);
        }

     @Override
     public void setAttribute(String namespace, String localName, String value) 
     {
       if (!Constants.ATTR_MUST_UNDERSTAND.equals(localName)) 
       {  // Or any other attribute name you'd want to avoid
         super.setAttribute(namespace, localName, value);
       }
     }
}

Создайте элемент заголовка следующим образом:

 ADESHeaderElement custheader = new ADESHeaderElement(qname, clientserv);          
        custheader.setActor(null);
person Santosh    schedule 08.05.2015

Когда вы создаете свой сервис из классов, сгенерированных cxf, добавьте собственный перехватчик

Service service = new MyService(wsdlURL, new QName("http://myservice.com/MyService/", "MyService"));
MyPort port = service.getMyPort();
Client client = ClientProxy.getClient(port);
// adding interceptor programmatically
client.getOutInterceptors().add(new MyHeaderHandler());

Вы можете расширить AbstractSoapInterceptor, чтобы реализовать собственный перехватчик для обработки сообщений.

import javax.xml.bind.JAXBException;
import javax.xml.namespace.QName;

import org.apache.cxf.binding.soap.interceptor.AbstractSoapInterceptor;
import org.apache.cxf.headers.Header;
import org.apache.cxf.jaxb.JAXBDataBinding;
import org.apache.cxf.phase.Phase;

import com.rpc.core.utils.DomainContext;

public class MyHeaderHandler extends AbstractSoapInterceptor {

    /**
    * Constructor
    */
    public MyHeaderHandler() {
        super(Phase.PRE_LOGICAL);

    }

    @Override
    public void handleMessage(org.apache.cxf.binding.soap.SoapMessage message) throws org.apache.cxf.interceptor.Fault {
        try {
            message.getHeaders().add(new Header(new QName("MyCustomHeader"),"value", new JAXBDataBinding(String.class)));
             } catch (JAXBException e) {
                 e.printStackTrace();
             }
         };
     }
}
person A Kunin    schedule 09.06.2016

Да, я сделал то же самое, что и Рангаппа Тунгал, следуя этому примеру:

Service w = new ServiceLocator();  
ServiceSoap ws = new ServiceSoapStub(new URL(w.getServiceSoapAddress()),w); Stub mystub = (Stub) ws;
AuthHeader up = new AuthHeader("user","pass");
mystub.setHeader("namespace", "AuthHeader", up);
ws.get***();

Ссылка на пример!

person Oscarfm    schedule 23.08.2013