我有一个很简单的方法,我用JAX-WS注释在WS API中使用:
@WebMethod public MyResponse sendSingle2( @WebParam(name="username") String username,@WebParam(name="password") String password,@WebParam(name="newParam") String newParam) { // the code }
现在我想要newParam是可选的.我的意思是我希望该方法仍然工作不仅在传递xml参数为空时:
<ws:sendSingle2> <username>user</username> <password>pass</password> <newParam></newParam> </ws:sendSingle2>
而且当它不存在时:
<ws:sendSingle2> <username>user</username> <password>pass</password> </ws:sendSingle2>
我需要它不要破坏现有的API,没有新的参数.
解决方法
通常,参数的可选性通过模式minOccurs = 0设置.此外,您可以在模式中定义一个Request参数,而不是使用多个参数,您将其定义为WebMethod的参数.可选性现在封装在参数中,并且对于具有或不具有可选参数的调用调用相同的方法.
我更喜欢先定义合同,而不是依赖于自动生成的文件.一旦你知道XSD,SOAP和WSDL如何一起玩,你就不用再使用基于注释/基于代码的定义,因为你的灵活性比较灵活.
代码示例:
<xs:schema targetNamespace="http://your.namespace.com" xmlns:tns="http://your.namespace.com" xmlns:xs="http://www.w3.org/2001/XMLSchema" elementFromDefault="qualified" attributeFromDefault="qualified"> ... <xs:element name="MyRequest" type="tns:MyRequestType" /> <xs:element name="MyResponse" type="tns:MyResponseType" /> <xs:complexType name"MyRequestType"> <xs:sequence> <xs:element name="username" type="xs:string" minOccurs="1" maxOccurs="1" /> <xs:element name="password" type="xs:string" minOccurs="1" maxOccurs="1" /> <xs:element name="newParam" type="xs:string" minOccurs="0" maxOccurs="1" /> </xs:sequence> </xs:complexType> ... </xs:schema>
在您的WSDL文件中,您定义了如下消息:
<wsdl:definitions xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/" xmlns:msg="http://your.namespace.com" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:http="http://schemas.xmlsoap.org/wsdl/http/" xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/" xmlns:soapenc="http://schemas.xmlsoap.org/soap/encoding/" targetNamespace="http://your.namespace.com"> <wsdl:types> <xs:schema> <!-- either import the externalized schema --> <xs:import namespace="http://your.namespace.com" schemaLocation="someDir/yourMessageSchema.xsd" /> </xs:schema> <!-- or define the schema within the WSDL - just copy the schema here --> <xs:schema targetNamespace="http://your.namespace.com" xmlns:tns="http://your.namespace.com" xmlns:xs="http://www.w3.org/2001/XMLSchema" elementFromDefault="qualified" attributeFromDefault="qualified"> ... </xs:schema> </wsdl:types> ... <wsdl:message name="sendSingle2Request"> <wsdl:part name="in" element="msg:MyRequest" /> </wsdl:message> <wsdl:message name="sendSingle2Response"> <wsdl:part name="out" element="msg:MyResponse" /> </wsdl:message> ... <wsdl:portType name="YourServiceEndpoint"> <wsdl:operation name="sendSingle2"> <wsdl:input message="tns:sendSingle2Request" /> <wsdl:output message="tns:sendSingle2Response" /> </wsdl:operation> ... </wsdl:portType> <wsdl:binding name="YourServiceBinding" type="YourServiceEndpoint"> <soap:binding style="document" transport="http://schemas.xmlsoap.org/soap/http" /> <wsdl:operation name=""sendSingle2"> <soap:operation soapAction="http://your.namespace.com/SendSingle2" style="document" /> <wsdl:input> <soap:body parts="in" use="literal" /> </wsdl:input> <wsdl:output> <soap:body parts="out" use="literal" /> </wsdl:output> </wsdl:operation> ... </wsdl:binding> <wsdl:service name="YourService"> <wsdl:port name="YourServicePort binding="tns:YourServiceBinding"> <soap:address location="http://your.server:port/path/to/the/service" /> </wsdl:port> </wsdl:service> </wsdl:definitions>
这里的WSDL协议定义为使用style:document / literal,并且在模式的帮助下,实际的SOAP消息将是文档/文字包装,此外WS-I兼容.
因此,您的方法将更改为公共MyResponse sendSinge2(MyRequest请求),其中请求现在封装username,passowrd和newParam.如果newParam没有发送SOAP请求,它只会返回null,所以在使用它之前先检查一下.
如果你坚持使用代码优先的方法,那么您需要首先定义您的MyRequest类,将其用作请求参数,而不是2或3的值.
@XmlAccessorType(XmlAccessType.FIELD) @XmlRootElement(name = "MyRequest",namespace="http://your.namespace.com") public class MyRequest implements Serializable { @XmlElement(name = "username",required = true) protected String username; @XmlElement(name = "password",required = true) protected String password; @XmlElement(name = "newParam",required = false) protected String newParam; ... }
如果还没有完成,MyResult也应该这样做. web方法现在可以看起来像这样:
@WebMethod(operationName = "sendSingle2") @WebResult(name = "sendSingle2Response",targetNamespace = "http://your.namespace.com") public MyResult sendSingle2(@WebParam(name = "sendSingle2Request") MyRequest request) { ... }
再次,请求封装你的第一个参数,你可以检查可选参数是否为空.
HTH