我有一个非常简单的方法,可以通过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,该API在没有新参数的情况下也可以工作。
@WebParam将消息部分映射到参数,并且部分不是可选的。请参阅WSDL中的可选消息部分。因此,简短的答案就是您要问的事情根本无法完成。但是,如果可以重构此方法,则可以使用下面描述的方法之一。
通常,参数的可选性是通过schema设置的minOccurs=0。此外,除了使用多个参数,您还可以在架构中定义一个Request参数,并将其定义为的参数WebMethod。现在,可选项被封装在参数中,并在具有或不具有可选参数的情况下调用相同的方法。
minOccurs=0
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合同定义为使用样式:document/literal借助于模式,实际的SOAP消息将与document/literal wrappedWS-I兼容。
document/literal
document/literal wrapped
因此,您的方法将改变公众MyResponse sendSinge2(MyRequest request)地方request现在封装username,passowrd和newParam。如果newParam未随SOAP请求一起发送,它将简单地返回null,因此最好在使用它之前先检查一下。
MyResponse sendSinge2(MyRequest request)
request
username
passowrd
newParam
null
如果坚持以代码为先的方法,则需要首先定义MyRequest用作请求参数的类,而不是那些2或3的值。
MyRequest
@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方法现在可能看起来像这样:
MyResult
@WebMethod(operationName = "sendSingle2") @WebResult(name = "sendSingle2Response", targetNamespace = "http://your.namespace.com") public MyResult sendSingle2(@WebParam(name = "sendSingle2Request") MyRequest request) { ... }
同样,request将3个参数封装起来,您首先要检查可选参数是否为null。
高温超导