我有一个非常简单的方法,可以通过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
。现在,可选项被封装在参数中,并在具有或不具有可选参数的情况下调用相同的方法。
我更喜欢先定义合同,而不要依赖自动生成的文件。一旦弄清楚了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 wrapped
WS-I兼容。
因此,您的方法将改变公众MyResponse sendSinge2(MyRequest request)
地方request
现在封装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)
{
...
}
同样,request
将3个参数封装起来,您首先要检查可选参数是否为null。
高温超导
问题内容: 在Spring 3.0中,我可以有一个可选的path变量吗? 例如 在这里我想还是要调用相同的方法。 一种明显的解决方法是声明为请求参数: 然后/json?type=abc&track=aa或/json?track=rr将工作 问题答案: 你不能具有可选的路径变量,但是可以有两个调用相同服务代码的控制器方法:
我想使用可选实用程序在JDK8中执行空检查。这是我写的代码,给我一个错误: 这里可以显示或不显示“jcr:description”。如果它存在,我想在description变量中使用该值,如果为null,只需为description设置空白字符串。这里也可以使用Lambda表达式吗?谢谢
问题内容: 为什么无法对隐式解包的可选变量进行突变? 这是一个重现问题的简短示例: 带整数 问题答案: 更新: Xcode Beta 5中的一个小警告已解决此问题: 该数组可以按预期工作,但是现在看来整数仍然需要显式拆包以允许使用 当前,这仅仅是Optionals的本质(无论是否隐式解包)。unwrap运算符返回一个不变的值。这可能是固定的,或者将来会提供更好的解决方案。 目前唯一的解决方法是将数
我有下面的路由和bean来从属性文件中获取消息。在一些消息中,我必须替换消息中的参数。因此,我在bean中寻找一个不编写2个方法的解决方案,一个是带参数的(),另一个是不带参数的()。 它是否可以通过在路由中使用DSL来摆脱bean中的,或者使中的参数可选,以便我在bean中最后有一个方法? 路线 豆
当使用Java8类时,有两种方法可以将值包装到Optional中。 我理解是使用的唯一安全方法,但为什么?为什么不直接使用
问题: 我有一个服务,接受一个字符串作为输入。每当某些字段不总是存在时,JSON模式都不同。当这些字段存在时,我如何使用Jayway的查询它们的值? 我尝试过的: 我使用了 返回如果路径没有找到,但是我的代码仍然抛出: 通用域名格式。乱穿马路。jsonpath。PathNotFoundException:路径$['somepath'中缺少属性 当我给它一个不存在的路径。有人知道这可能是什么原因吗?