我正在尝试清理一些JAX-WS带注释代码优先的Web服务,以便为任何实现客户端生成最佳和干净的wsdl文件。我遇到了一个问题,其中一个正在使用某个Web服务中的参数(in和out)的类扩展自HashMap<String,String>
。不使用任何类型的适配器,这会在wsdl中生成如下所示的xml:
<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)
但是,我注意到仍然在WSDL中定义了attributeSet,hashMap和abstractMap类型的类型层次结构,即使没有其他类型通过它们扩展,并且类型不在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中删除它们。这是我需要帮助的地方 - 如何在我的代码第一个界面中仍然使用AttributeSet的同时从我的wsdl类型中删除Map和AbstractMap?
如果它有助于我使用Apache CXF 2.3.1作为我的JAXB绑定的JAX-WS实现......虽然我不知道CXF是否与WSDL生成有关。
免责声明:我每次机会都会尝试提倡和实践WSDL-first SOAP开发......但是,我正在研究的特定项目导致了这个问题已经决定了代码 - 他们的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();
}
}