java - 如何创建在soap header 中需要用户名/密码的soap服务

标签 java web-services soap wsdl

请让我澄清我的要求。以下是我所知道/了解到的相关要求。

  1. 添加 ws-security header 。 (我使用 apache Rampart 完成此操作。使用 UsernameToken 进行身份验证) http://www.ibm.com/developerworks/library/j-jws4/
  2. 访问 Web 服务的容器级安全约束(我使用了 web.xml 中所需的配置) http://www.mkyong.com/webservices/jax-ws/container-authentication-with-jax-ws-tomcat/
  3. 用户名/密码绑定(bind)为 Http 请求 header 的应用程序级别。 http://www.mkyong.com/webservices/jax-ws/application-authentication-with-jax-ws/

以上三种方式我不想要。我的要求是添加采用 username/password 的自定义 header 元素。对于我们的一位客户,我遇到了这个要求。他们的 wsdl 部分如下

<s:element name="AuthenticationHeader" type="tns:AuthenticationHeader" />
      <s:complexType name="AuthenticationHeader">
        <s:sequence>
          <s:element minOccurs="0" maxOccurs="1" name="UserName" type="s:string" />
          <s:element minOccurs="0" maxOccurs="1" name="Password" type="s:string" />
        </s:sequence>
        <s:anyAttribute />
      </s:complexType>

前缀 s= http://www.w3.org/2001/XMLSchema 的 xmlns

在客户端,我通过在soap header 中提供上述复杂类型元素来使用该服务

现在我想知道如何创建一个 SOAP 服务,它将接受上述 SOAP 头。

提前致谢

最佳答案

此外,我在提供的 XSD 中发现了一些可能会更好的内容。复杂类型可以为全局元素指定不同的名称。

<s:element name="AuthenticationHeader" type="tns:AuthenticationHeaderType" />
      <s:complexType name="AuthenticationHeaderType">
        <s:sequence>
          <s:element minOccurs="0" maxOccurs="1" name="UserName" type="s:string" />
          <s:element minOccurs="0" maxOccurs="1" name="Password" type="s:string" />
        </s:sequence>
        <s:anyAttribute />
      </s:complexType>

如果 xsd 如上所述,则实现如下

  AuthenticationHeader authenticationHeader = new AuthenticationHeader();
 AuthenticationHeaderType authenticationHeaderType = new AuthenticationHeaderType();
    authenticationHeaderType.setUsername("MyUsername");
    authenticationHeaderType.setPassword("MyPassword");

authenticationHeader.setAuthenticationHeader(authenticationHeaderType ); 

将上述authenticationHeader对象与Web服务请求对象一起附加。

<小时/>

您的示例将根据我从您提供的 block 中准备的 xsd 创建以下类

<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"
    attributeFormDefault="unqualified" elementFormDefault="unqualified">
<xs:element name="AuthenticationHeader" type="AuthenticationHeader" />
      <xs:complexType name="AuthenticationHeader">
        <xs:sequence>
          <xs:element minOccurs="0" maxOccurs="1" name="UserName" type="xs:string" />
          <xs:element minOccurs="0" maxOccurs="1" name="Password" type="xs:string" />
        </xs:sequence>
        <xs:anyAttribute />
      </xs:complexType>
      </xs:schema>

生成的类如下

ObjectFactory.java

import javax.xml.bind.JAXBElement;
import javax.xml.bind.annotation.XmlElementDecl;
import javax.xml.bind.annotation.XmlRegistry;
import javax.xml.namespace.QName;


/**
 * This object contains factory methods for each 
 * Java content interface and Java element interface 
 * generated in the com.auth package. 
 * <p>An ObjectFactory allows you to programatically 
 * construct new instances of the Java representation 
 * for XML content. The Java representation of XML 
 * content can consist of schema derived interfaces 
 * and classes representing the binding of schema 
 * type definitions, element declarations and model 
 * groups.  Factory methods for each of these are 
 * provided in this class.
 * 
 */
@XmlRegistry
public class ObjectFactory {

    private final static QName _AuthenticationHeader_QNAME = new QName("", "AuthenticationHeader");

    /**
     * Create a new ObjectFactory that can be used to create new instances of schema derived classes for package: com.auth
     * 
     */
    public ObjectFactory() {
    }

    /**
     * Create an instance of {@link AuthenticationHeader }
     * 
     */
    public AuthenticationHeader createAuthenticationHeader() {
        return new AuthenticationHeader();
    }

    /**
     * Create an instance of {@link JAXBElement }{@code <}{@link AuthenticationHeader }{@code >}}
     * 
     */
    @XmlElementDecl(namespace = "", name = "AuthenticationHeader")
    public JAXBElement<AuthenticationHeader> createAuthenticationHeader(AuthenticationHeader value) {
        return new JAXBElement<AuthenticationHeader>(_AuthenticationHeader_QNAME, AuthenticationHeader.class, null, value);
    }

}

AuthenticationHeader.java

import java.util.HashMap;
import java.util.Map;
import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlAnyAttribute;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlType;
import javax.xml.namespace.QName;


/**
 * <p>Java class for AuthenticationHeader complex type.
 * 
 * <p>The following schema fragment specifies the expected content contained within this class.
 * 
 * <pre>
 * &lt;complexType name="AuthenticationHeader">
 *   &lt;complexContent>
 *     &lt;restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
 *       &lt;sequence>
 *         &lt;element name="UserName" type="{http://www.w3.org/2001/XMLSchema}string" minOccurs="0"/>
 *         &lt;element name="Password" type="{http://www.w3.org/2001/XMLSchema}string" minOccurs="0"/>
 *       &lt;/sequence>
 *       &lt;anyAttribute/>
 *     &lt;/restriction>
 *   &lt;/complexContent>
 * &lt;/complexType>
 * </pre>
 * 
 * 
 */
@XmlAccessorType(XmlAccessType.FIELD)
@XmlType(name = "AuthenticationHeader", propOrder = {
    "userName",
    "password"
})
public class AuthenticationHeader {

    @XmlElement(name = "UserName")
    protected String userName;
    @XmlElement(name = "Password")
    protected String password;
    @XmlAnyAttribute
    private Map<QName, String> otherAttributes = new HashMap<QName, String>();

    /**
     * Gets the value of the userName property.
     * 
     * @return
     *     possible object is
     *     {@link String }
     *     
     */
    public String getUserName() {
        return userName;
    }

    /**
     * Sets the value of the userName property.
     * 
     * @param value
     *     allowed object is
     *     {@link String }
     *     
     */
    public void setUserName(String value) {
        this.userName = value;
    }

    /**
     * Gets the value of the password property.
     * 
     * @return
     *     possible object is
     *     {@link String }
     *     
     */
    public String getPassword() {
        return password;
    }

    /**
     * Sets the value of the password property.
     * 
     * @param value
     *     allowed object is
     *     {@link String }
     *     
     */
    public void setPassword(String value) {
        this.password = value;
    }

    /**
     * Gets a map that contains attributes that aren't bound to any typed property on this class.
     * 
     * <p>
     * the map is keyed by the name of the attribute and 
     * the value is the string value of the attribute.
     * 
     * the map returned by this method is live, and you can add new attribute
     * by updating the map directly. Because of this design, there's no setter.
     * 
     * 
     * @return
     *     always non-null
     */
    public Map<QName, String> getOtherAttributes() {
        return otherAttributes;
    }

}

您可以通过以下方式实现您的代码

public class ImplementAuthentication {

    void authentication() {

        AuthenticationHeader authenticationHeader = new AuthenticationHeader();

        authenticationHeader.setPassword("MyPassword");
        authenticationHeader.setUserName("MyUsername");

        ObjectFactory obj = new ObjectFactory();

        obj.createAuthenticationHeader(authenticationHeader);
    }
}

关于java - 如何创建在soap header 中需要用户名/密码的soap服务,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31179900/

相关文章:

iphone - 使用 Core Data 访问远程数据的模式?

javascript - Magento 使用 Node JS/soap 包过滤 SOAP v2

wcf - SOAP、JSON 和 POX 在同一个安静的 wcf 中

Java:声明空构造函数以从另一个类初始化对象的替代方法

java - 如何使用 Hibernate Search 处理集合更新

c# - 如何让我的客户端应用程序将来 self 的网络服务的对象识别为它已知的类型?

c# - Java - 通过 Web 服务和 XML 发送可能包含非法字符的 UTF-8 字符串

c++ - gSoap:如何优雅地关闭 web 服务应用程序?

Java服务器套接字

java - mvn process-resources 不会拉下使用阴影插件创建的 uber jar