上下文:我有一个web服务,它返回一个家庭及其成员。一个家庭总是有一个父亲和一个母亲,没有孩子或多个孩子。服务的wsdl描述如下。
目的:我想有效地使用Java 8中的可选项,并避免使用检查null的经典方法。我所说的经典,是指在Java 7之前我们一直使用的实现方式。
如果我假设webservice总是返回一个族,那么这就足够了:
@Test
public void test1() {
Family f = helloWorldClientImplBean.allFamily();
f.getChildren().stream().filter(x -> x.getFirstName().equalsIgnoreCase("John")).findFirst()
.ifPresent(y -> System.out.println(y.getLastName()));
}
我做了测试,我可以看到,只要我的家庭得到服务的回应,无论我是否有孩子,这都是完美的。我的意思是,在下面的服务实现中,如果我对olderSon和youngSon代码进行了注释,那么将不会有任何空异常。
当服务返回null时会出现问题。
在阅读了几篇博客并进行了讨论之后,我找到了这段代码,它可以正确地检查服务返回是否为null。
@Test
public void testWorkingButSeemsOdd() {
//Family f = helloWorldClientImplBean.allFamily();
Family f = null; //to make simple the explanation
Optional<Family> optFamily = Optional.ofNullable(f);
if (optFamily.isPresent()) {
optFamily.filter(Objects::nonNull).map(Family::getChildren).get().stream().filter(Objects::nonNull)
.filter(x -> x.getFirstName().equalsIgnoreCase("John")).findFirst()
.ifPresent(y -> System.out.println("Optional: " + y.getLastName()));
}
对我来说,更干净的方法是以下方法之一(所有这些方法都失败了,但我相信它们可以显示出我一直在努力的方向):
//在这里,我尝试在映射之前过滤f是否不为null
@Test
public void testFilterNonNull() {
Family f = null;
Optional.ofNullable(f).filter(Objects::nonNull).map(Family::getChildren).get().stream().filter(Objects::nonNull)
.filter(x -> x.getFirstName().equalsIgnoreCase("John")).findFirst()
.ifPresent(y -> System.out.println(y.getLastName()));
}
我知道next无法编译,但我想可能会达到类似的效果
@Test
@Ignore
public void testOptionalNullable() {
Family f = helloWorldClientImplBean.allFamily();
Optional.ofNullable(f).orElse(System.out.println("Family is null")).map(Family::getChildren).get().stream().filter(Objects::nonNull)
.filter(x -> x.getFirstName().equalsIgnoreCase("John")).findFirst()
.ifPresent(y -> System.out.println(y.getLastName()));
}
wsdl
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<wsdl:definitions targetNamespace="http://codenotfound.com/services/helloworld"
xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/" xmlns:tns="http://codenotfound.com/services/helloworld"
xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/" xmlns:xsd="http://www.w3.org/2001/XMLSchema"
name="HelloWorld">
<wsdl:types>
<schema targetNamespace="http://codenotfound.com/services/helloworld"
xmlns="http://www.w3.org/2001/XMLSchema" xmlns:tns="http://codenotfound.com/services/helloworld"
elementFormDefault="qualified" attributeFormDefault="unqualified"
version="1.0">
<element name="family">
<complexType>
<sequence>
<element name="father" type="tns:persontype" minOccurs="1"
maxOccurs="1" />
<element name="mother" type="tns:persontype" minOccurs="1"
maxOccurs="1" />
<element name="children" type="tns:persontype" minOccurs="0"
maxOccurs="unbounded" />
</sequence>
</complexType>
</element>
<complexType name="persontype">
<sequence>
<element name="firstName" type="xsd:string" />
<element name="lastName" type="xsd:string" />
</sequence>
</complexType>
<element name="EmptyParameter" type="tns:voidType" />
<complexType name="voidType">
<sequence />
</complexType>
</schema>
</wsdl:types>
<!-- Message -->
<wsdl:message name="emptyRequest">
<wsdl:part name="emptyParameter" element="tns:EmptyParameter" />
</wsdl:message>
<wsdl:message name="allFamiliesResponse">
<wsdl:part name="allFamiliesResponse" element="tns:family" />
</wsdl:message>
<!-- PortType -->
<wsdl:operation name="allFamilies">
<wsdl:input message="tns:emptyRequest" />
<wsdl:output message="tns:allFamiliesResponse"></wsdl:output>
</wsdl:operation>
</wsdl:portType>
<!-- Binding -->
<wsdl:binding name="HelloWorld_Binding" type="tns:HelloWorld_PortType">
<soap:binding style="document"
transport="http://schemas.xmlsoap.org/soap/http" />
<wsdl:operation name="allFamilies">
<wsdl:input>
<soap:body use="literal" />
</wsdl:input>
<wsdl:output>
<soap:body use="literal" />
</wsdl:output>
</wsdl:operation>
</wsdl:binding>
<wsdl:service name="HelloWorld_Service">
<wsdl:port name="HelloWorld_Port" binding="tns:HelloWorld_Binding">
<soap:address location="http://localhost:9090/cnf/services/helloworld" />
</wsdl:port>
</wsdl:service>
</wsdl:definitions>
服务实施的相关部分:
@Override
public Family allFamilies(VoidType emptyParameter) {
ObjectFactory factory = new ObjectFactory();
Family result = factory.createFamily();
Persontype father = new Persontype();
father.setFirstName("Jose");
father.setLastName("Pereira");
Persontype mother = new Persontype();
mother.setFirstName("Maria");
mother.setLastName("Pereira");
result.setFather(father);
result.setMother(mother);
Persontype olderSon = new Persontype();
olderSon.setFirstName("John");
olderSon.setLastName("Pereira");
Persontype youngerSon = new Persontype();
youngerSon.setFirstName("Ana");
youngerSon.setLastName("Pereira");
result.getChildren().add(olderSon);
result.getChildren().add(youngerSon);
return result;
}
因此,我的直接问题是:根据我上面描述的wsdl场景及其实现,通过使用isPresent()来检查web服务返回是否为null的真正唯一方法是否与我们使用经典null检查(if(f!=null){…)的方法非常相似?