Избавьтесь от лишних нежелательных complexTypes из WSDL, сгенерированного первым кодом - CXF с привязкой JAXB - PullRequest
1 голос
/ 13 декабря 2010

Я пытаюсь очистить некоторые аннотированные веб-службы с кодом JAX-WS, чтобы они создавали оптимальные и чистые wsdl-файлы для любых внедряющих клиентов.Я столкнулся с проблемой, когда один из классов, который использует параметр (как входящий, так и выходящий) в конкретном веб-сервисе, расширяется от HashMap<String,String>.Без использования какого-либо адаптера это создает XML в wsdl, который выглядит следующим образом:

<xs:complexType abstract="true" name="abstractMap">
 <xs:sequence/>
</xs:complexType>

<xs:complexType name="hashMap">
 <xs:complexContent>
   <xs:extension base="tns:abstractMap">
     <xs:sequence/>
   </xs:extension>
 </xs:complexContent>
</xs:complexType>

<xs:complexType name="attributeSet">
 <xs:complexContent>
   <xs:extension base="tns:hashMap">
     <xs:sequence/>
   </xs:extension>
 </xs:complexContent>
</xs:complexType>

У нас есть класс адаптера JAXB, который мы используем, и мы указываем этот адаптер на JAX-Сам аннотированный интерфейс WS, который заставляет определенный в wsdl для этих операций использовать надлежащий тип, а не эту довольно бесполезную иерархию типов выше.Аннотированный метод JAX-WS выглядит следующим образом:

void assignPrincipalToRole(@WebParam(name="principalId") String principalId, 
    @WebParam(name="namespaceCode") String namespaceCode, 
    @WebParam(name="roleName") String roleName, 
    @WebParam(name="qualifications") @XmlJavaTypeAdapter(value = AttributeSetAdapter.class) AttributeSet qualifications)

Однако я заметил, что иерархия типов для типов attributeSet, hashMap и abstractMap все еще определяется в WSDL, даже если другие типы не выходят изих через и типы не используются где-либо еще в wsdl.

Теперь я могу сделать что-то вроде пометки класса AttributeSet как @ XmlTransient

@XmlTransient
public class AttributeSet extends HashMap<String,String> {

И это удерживает <xs:complexType name="attributeSet"> от WSDL, как и ожидалось, но пока <xs:complexType name="hashMap"> и <xs:complexType abstract="true" name="abstractMap"> все еще остаются в WSDL.

Возможно, я слишком одержим, но наличие этих типов в WSDL просто уродливо и вводит в заблуждение, но я не могу точно сказать, почему они вообще включены или как удалить их из WSDLполностью.Вот где мне нужна помощь - как избавиться от Map и AbstractMap от моих типов wsdl, все еще используя AttributeSet в моем интерфейсе первого кода?

Если это поможет, я использую Apache CXF 2.3.1 в качествемоя реализация JAX-WS с привязкой JAXB ... хотя я не знаю, имеет ли CXF какое-либо отношение к генерации WSDL.

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


Редактировать : Вот копия / вставка класса AttributeSet (без @XmlTransient, так как я отменил изменение, из-за того, что оно не принесло пользы).На самом деле это всего лишь класс с явным именем для Map с добавленным методом для форматированного вывода.

public class AttributeSet extends HashMap<String,String> {

    private static final long serialVersionUID = -5960854367616060667L;

    public AttributeSet() {
        super();
    }

    /**
     * Create an AttributeSet with a single key/value pair.
     */
    public AttributeSet( String key, String value ) {
        this();
        put( key, value );
    }

    /**
     * @see HashMap#HashMap(int)
     * 
     * @param initialSize
     */
    public AttributeSet( int initialSize ) {
        super( initialSize );
    }

    public AttributeSet( Map<String,String> map ) {
        super();
        if ( map != null ) {
            putAll( map );
        }
    }

    public String formattedDump( int indent ) {
        int maxKeyLen = 1;
        for ( String key : this.keySet() ) {
            if ( key.length() > maxKeyLen ) {
                maxKeyLen = key.length();
            }
        }
        StringBuffer sb = new StringBuffer();
        String indentStr = StringUtils.repeat( " ", indent );
        for ( String key : this.keySet() ) {
            sb.append( indentStr );
            sb.append( StringUtils.rightPad( key, maxKeyLen, ' ' ));
            sb.append( " --> " );
            sb.append( get( key ) );
            sb.append( '\n' );
        }
        return sb.toString();
    }
}
...