我在 WSO2 ESB 中创建了一个代理服务,该服务从没有参数的 web 服务获取请求,并基于 xml 文件进行响应。这是我的 WSDL(名为 itemcat.wsdl):
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<wsdl:definitions xmlns:scc="http://www.myplace.com/scc/" xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/"
xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" name="ItemCategories"
targetNamespace="http://www.myplace.com/scc/">
<wsdl:types>
<xsd:schema targetNamespace="http://www.myplace.com/scc/">
<xsd:element name="ItemCategoriesRequest">
<xsd:annotation>
<xsd:documentation>No parameter for request</xsd:documentation>
</xsd:annotation>
<xsd:complexType />
</xsd:element>
<xsd:element name="ItemCategoriesResponse">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="ItemCategories" type="scc:ItemCategoriesType" minOccurs="1" maxOccurs="1" />
</xsd:sequence>
</xsd:complexType>
</xsd:element>
<xsd:complexType name="ItemCategoriesType">
<xsd:sequence>
<xsd:element name="ItemCategory" type="scc:ItemCategoryType" minOccurs="0" maxOccurs="unbounded" />
</xsd:sequence>
</xsd:complexType>
<xsd:complexType name="ItemCategoryType">
<xsd:attribute name="value" use="required" type="scc:ValueType" />
<xsd:attribute name="description" use="optional" type="scc:DescriptionType" />
</xsd:complexType>
<xsd:simpleType name="ValueType">
<xsd:annotation>
<xsd:documentation>Unique category name</xsd:documentation>
</xsd:annotation>
<xsd:restriction base="xsd:string">
<xsd:maxLength value="30" />
</xsd:restriction>
</xsd:simpleType>
<xsd:simpleType name="DescriptionType">
<xsd:annotation>
<xsd:documentation>Category description</xsd:documentation>
</xsd:annotation>
<xsd:restriction base="xsd:string">
<xsd:maxLength value="255" />
</xsd:restriction>
</xsd:simpleType>
</xsd:schema>
</wsdl:types>
<wsdl:message name="ItemCategoriesRequestMsg">
<wsdl:part element="scc:ItemCategoriesRequest" name="parameters" />
</wsdl:message>
<wsdl:message name="ItemCategoriesResponseMsg">
<wsdl:part element="scc:ItemCategoriesResponse" name="parameters" />
</wsdl:message>
<wsdl:portType name="ItemCategoriesPortType">
<wsdl:operation name="getItemCategories">
<wsdl:input message="scc:ItemCategoriesRequestMsg" name="ItemCategoriesRequest" />
<wsdl:output message="scc:ItemCategoriesResponseMsg" name="ItemCategoriesResponse"/>
</wsdl:operation>
</wsdl:portType>
<wsdl:binding name="ItemCategoriesSoap11Binding" type="scc:ItemCategoriesPortType">
<soap:binding style="document" transport="http://schemas.xmlsoap.org/soap/http" />
<wsdl:operation name="getItemCategories">
<soap:operation soapAction="itemcategories" />
<wsdl:input>
<soap:body use="literal" />
</wsdl:input>
<wsdl:output>
<soap:body use="literal" />
</wsdl:output>
</wsdl:operation>
</wsdl:binding>
<wsdl:service name="ItemCategoriesService">
<wsdl:port binding="scc:ItemCategoriesSoap11Binding" name="ItemCategoriesEndPoint">
<soap:address location="http://www.myplace.com/scc/itemcategories" />
</wsdl:port>
</wsdl:service>
</wsdl:definitions>
我的代理:
<?xml version="1.0" encoding="UTF-8"?>
<proxy xmlns="http://ws.apache.org/ns/synapse" name="ItemCategoriesService" transports="http https" startOnLoad="true" trace="disable">
<target>
<inSequence>
<sequence key="ItemCategoriesSequence"/>
</inSequence>
<outSequence/>
<faultSequence/>
</target>
<publishWSDL key="gov:/scc/itemcat.wsdl"/>
<parameter name="useOriginalwsdl">true</parameter>
<parameter name="modifyUserWSDLPortAddress">true</parameter>
</proxy>
和顺序:
<sequence xmlns="http://ws.apache.org/ns/synapse" name="ItemCategoriesSequence">
<header action="remove" name="To"/>
<property action="set" name="RESPONSE" scope="default" type="STRING" value="true"/>
<property action="remove" name="NO_ENTITY_BODY" scope="axis2"/>
<property action="set" name="FileLocation" scope="default"
type="STRING" value="/home/user/Desktop/itemcat.txt"/>
<class name="com.myplace.esb.mediator.ItemCategoriesTextFile"/>
<send/>
</sequence>
最后是用于解析文本文件的调解器(我使用 JABX 库 - 我没有在此处粘贴 ItemCategories.java 和 ItemCategory.java 文件,但它们很简单):
import java.io.ByteArrayInputStream;
import java.io.File;
import java.io.IOException;
import java.io.StringWriter;
import javax.validation.Validation;
import javax.xml.bind.JAXBContext;
import javax.xml.bind.Marshaller;
import org.apache.axiom.om.OMElement;
import org.apache.axiom.om.OMXMLBuilderFactory;
import org.apache.commons.io.FileUtils;
import org.apache.commons.io.LineIterator;
import org.apache.synapse.MessageContext;
import org.apache.synapse.mediators.AbstractMediator;
public class ItemCategoriesTextFile extends AbstractMediator {
/**
* Property name for file location.
*/
private static final String FILE_LOCATION = "FileLocation";
/**
* File content parameters.
*/
private static final int EXPECTED_COLUMNS = 2;
private static final String COLUMN_SEPARATOR_REGEXP = "\\t";
@Override
public boolean mediate(MessageContext context) {
final String property = (String) context.getProperty(FILE_LOCATION);
if (property == null) {
log.warn("Property [" + FILE_LOCATION + "] null");
return false;
}
final ItemCategories categories = new ItemCategories();
LineIterator it;
try {
it = FileUtils.lineIterator(new File(property));
} catch (IOException e) {
log.warn("Error processing file [" + property + "]", e);
return false;
}
// iterate over each line
try {
while (it.hasNext()) {
final String line = it.nextLine();
final boolean parsed = parseLine(categories, line);
if (!parsed) {
// something went wrong
return false;
}
}
} finally {
LineIterator.closeQuietly(it);
}
try {
response(context, categories, ItemCategories.class);
} catch (Exception e) {
log.warn("Error processing xml", e);
return false;
}
return true;
}
private boolean parseLine(final ItemCategories itemcats, final String line) {
final String[] split = line.split(COLUMN_SEPARATOR_REGEXP,
EXPECTED_COLUMNS);
if (split.length != EXPECTED_COLUMNS) {
log.warn("Expected [" + EXPECTED_COLUMNS
+ "] or less columns for each line inside the file");
return false;
}
final ItemCategory itemcat = new ItemCategory(split[0], split[1]);
if (!Validation.buildDefaultValidatorFactory().getValidator()
.validate(itemcat).isEmpty()) {
log.warn("Constraints not satisfied for line [" + line + "]");
return false;
}
itemcats.addItemCategory(itemcat);
return true;
}
/**
*
* @param context
* response message context.
* @param data
* data that will go to xml.
* @param clazz
* class on top of xml.
* @throws Exception
* any problem parsing xml.
*/
private void response(MessageContext context, final Object data,
final Class<?> clazz) throws Exception {
final JAXBContext jc = JAXBContext.newInstance(clazz);
final Marshaller marshaller = jc.createMarshaller();
final StringWriter writer = new StringWriter();
// removes the <xml> tag
marshaller.setProperty(Marshaller.JAXB_FRAGMENT, Boolean.TRUE);
marshaller.marshal(data, writer);
final OMElement root = OMXMLBuilderFactory.createOMBuilder(
new ByteArrayInputStream(writer.toString().getBytes()))
.getDocumentElement();
context.getEnvelope().getBody().addChild(root);
}
这是文本文件(itemcat.txt):
Raw Raw
Component General
Intermediate Intermediate
Finished Finished
使用 WSO2 ESB 控制台上的“尝试此服务”,我得到了好的结果:
<ItemCategories>
<ItemCategory value="Intermediate" description="Intermediate"/>
<ItemCategory value="Component" description="General"/>
<ItemCategory value="Finished" description="Finished"/>
<ItemCategory value="Raw" description="Raw"/>
</ItemCategories>
然后下一步是创建一个 Web 服务客户端。我正在使用 CXF。我使用了wsdl2java 命令并为此创建了所有类。这是主要课程:
public class Main {
public static void main(String[] args) throws MalformedURLException {
URL url = new URL("http://localhost:8280/services/ItemCategoriesService?wsdl");
ItemCategoriesService service = new ItemCategoriesService(url);
ItemCategoriesPortType port = service.getItemCategoriesEndPoint();
ItemCategoriesResponse resp = port.getItemCategories(new ItemCategoriesRequest());
ItemCategories itens = resp.getItemCategories();
List<ItemCategory> list = itens.getItemCategory();
for(ItemCategory t : list){
System.out.println(t);
}
}
}
但我得到了一个 NullPointerException:
Exception in thread "main" java.lang.NullPointerException
at Main.main(Main.java:20)
第 20 行是
List<ItemCategory> list = itens.getItemCategory();
当我调试(使用 eclipse)中介代码时,我看到它里面的一切都很好。它返回正常。
谁能帮我找出为什么 web 服务客户端从服务器接收 null ?