如何在Android中通过POST请求查询Web服务?

时间:2012-02-11 01:39:21

标签: java android web-services jaxb ksoap2

我对Web Feature Service (WFS)完全不熟悉,但我希望在通过WFS发布数据的API之上构建一个带有ksoap2-android的Android应用程序。我想请求API中的数据传递边界框参数来限制将返回的数据。

问题:

  • 如何将GetFeature对象放入SOAP信封?
  • 如何在Android客户端上使用JAXBElement请参阅2012年3月15日的编辑

以下是API的一些链接,可能有助于了解其格式。

示例:WFS-1.1 GetFeature POST请求,http://data.wien.gv.at/daten/geoserver/wfs

<?xml version="1.0" encoding="UTF-8"?>
<wfs:GetFeature service="WFS" version="1.1.0"
  outputFormat="JSON"
  xmlns:ogdwien="http://www.wien.gv.at/ogdwien"
  xmlns:wfs="http://www.opengis.net/wfs"
  xmlns:ogc="http://www.opengis.net/ogc"
  xmlns:gml="http://www.opengis.net/gml"
  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xsi:schemaLocation="http://www.opengis.net/wfs
  http://schemas.opengis.net/wfs/1.1.0/wfs.xsd" >
 <wfs:Query typeName="ogdwien:BAUMOGD">
   <ogc:Filter>
   <ogc:BBOX>
   <ogc:PropertyName>SHAPE</ogc:PropertyName>
   <gml:Envelope srsName="http://www.opengis.net/gml/srs/epsg.xml#4326">
     <gml:lowerCorner>16.3739 48.2195</gml:lowerCorner>
     <gml:upperCorner>16.3759 48.2203</gml:upperCorner>
   </gml:Envelope>
   </ogc:BBOX>
   </ogc:Filter>
  </wfs:Query>
</wfs:GetFeature>

这是我现在提出的Android代码。这主要是examples from the ksoap2-android wiki启发的。我完全不确定 名称空间 methodName url 是否正确!

// KSOAP2Client.java

private class MyAsyncTask extends AsyncTask<Void, Void, Object> {
    String namespace = "http://www.wien.gv.at/ogdwien";
    String methodName = "GetFeature";
    String url = "http://data.wien.gv.at/daten/geoserver/wfs";

    protected Object doInBackground(Void... voids) {
        SoapSerializationEnvelope envelope = new SoapSerializationEnvelope(SoapEnvelope.VER11);
        envelope.dotNet = false;
        SoapObject soapObject = new SoapObject(namespace, methodName);
        envelope.setOutputSoapObject(soapObject);

        // TODO Put request parameters in the envelope. But how?

        try {
            HttpTransportSE httpTransportSE = new HttpTransportSE(url);
            httpTransportSE.debug = true;
            httpTransportSE.call(namespace + methodName, envelope);
            return (Object)soapSerializationEnvelope.getResponse();
        } catch (Exception exception) {
            exception.printStackTrace();
        }
        return null;
    }
}

编辑:2012年3月15日


我设法进一步,我几乎达到了似乎是解决方案。我找到了XML请求中使用的名称空间的schema definitions,并将它们链接到我的项目。这允许我为请求组装对象。

// TODO The core libraries won't work with Android.
import javax.xml.bind.JAXBElement;
import javax.xml.namespace.QName;

// TODO Not sure if the versions fit with the service.
import net.opengis.filter.v_1_1_0.BBOXType;
import net.opengis.filter.v_1_1_0.FilterType;
import net.opengis.filter.v_1_1_0.PropertyNameType;
import net.opengis.gml.v_3_1_1.DirectPositionType;
import net.opengis.gml.v_3_1_1.EnvelopeType;
import net.opengis.wfs.v_1_1_0.GetFeatureType;
import net.opengis.wfs.v_1_1_0.QueryType;

[...]

List<Double> lowerCornerList = new Vector<Double>();
lowerCornerList.add(16.3739);
lowerCornerList.add(48.2195);

List<Double> upperCornerList = new Vector<Double>();
upperCornerList.add(16.3759);
upperCornerList.add(48.2203);

DirectPositionType lowerCornerDirectPositionType = new DirectPositionType();
lowerCornerDirectPositionType.setValue(lowerCornerList);
DirectPositionType upperCornerDirectPositionType = new DirectPositionType();
upperCornerDirectPositionType.setValue(upperCornerList);

EnvelopeType envelopeType = new EnvelopeType();
envelopeType.setSrsName("http://www.opengis.net/gml/srs/epsg.xml#4326");
envelopeType.setLowerCorner(lowerCornerDirectPositionType);
envelopeType.setUpperCorner(upperCornerDirectPositionType);

List<Object> propertyNames = new Vector<Object>();
propertyNames.add(new String("SHAPE"));

PropertyNameType propertyNameType = new PropertyNameType();
propertyNameType.setContent(propertyNames);

// TODO Check parameters of JAXBElement.
JAXBElement<EnvelopeType> e = new JAXBElement<EnvelopeType>(null, null, envelopeType);
BBOXType bboxType = new BBOXType();
bboxType.setPropertyName(propertyNameType);
bboxType.setEnvelope(e);

// TODO Check parameters of JAXBElement.
JAXBElement<BBOXType> spatialOps = new JAXBElement<BBOXType>(null, null, bboxType);
FilterType filterType = new FilterType();
filterType.setSpatialOps(spatialOps);

QueryType queryType = new QueryType();
List<QName> typeNames = new Vector<QName>();
// TODO Check parameters of QName.
typeNames.add(new QName("ogdwien", "BAUMOGD"));
queryType.setTypeName(typeNames);

GetFeatureType featureType = new GetFeatureType();
featureType.setService("WFS");
featureType.setVersion("1.1.0");
featureType.setOutputFormat("JSON");
featureType.setMaxFeatures(new BigInteger("5"));

String namespace = "http://www.wien.gv.at/ogdwien";
String methodName = "GetFeature";
// TODO Is this the correct action?
String action = "http://data.wien.gv.at/daten/wfs?service=WFS&request=GetFeature&version=1.1.0&typeName=ogdwien:BAUMOGD&srsName=EPSG:4326";
String url = "http://data.wien.gv.at/daten/geoserver/wfs";

// TODO Is this the correct way to add GetFeature?
SoapObject soapObject = new SoapObject(namespace, methodName);
PropertyInfo propertyInfo = new PropertyInfo();
propertyInfo.setName("GetFeature");
propertyInfo.setValue(featureType);
soapObject.addProperty(propertyInfo);

仍有一个重大问题,还有一些小问题。主要问题是JAXBElement包含在Android拒绝使用的核心库javax.xml.bind.JAXBElement)中。小问题在评论和TODO中说明。

编辑:2012年4月27日


在我阅读this post时,我想我可能会遇到类似的问题。我还没有尝试过。

编辑:2012年5月9日


当你尝试为Android编译JAXBElement时,这是error message from Eclipse

2 个答案:

答案 0 :(得分:2)

@JJD我看到你在here给我留了一个消息
我有一段时间的会议,但我看了你的问题,并很乐意尽可能地帮助。我发现你在阅读模式定义时遇到了问题。你所拥有的这个定义是在另一个内部链接的,这就是为什么它让你感到困惑:

如果你继续:http://schemas.opengis.net/wfs/1.1.0/wfs.xsd

采用“GetCapabilities”方法,让我们在Web服务定义中读取它:

PS:我没有测试这些,但是:


现在您有了GetCapabilities的请求:

<!-- REQUEST -->
<xsd:element name="GetCapabilities" type="wfs:GetCapabilitiesType"/>
<xsd:complexType name="GetCapabilitiesType">
    <xsd:annotation>
    </xsd:annotation>
    <xsd:complexContent>
    <xsd:extension base="ows:GetCapabilitiesType">
    <xsd:attribute name="service" type="ows:ServiceType" use="optional" default="WFS"/>
    </xsd:extension>
    </xsd:complexContent>
</xsd:complexType>

GetCapabilities具有类型的复杂类型:GetCapabilitiesType,您可以在此页面的xsd链接中找到,正好“owsGetCapabilities.xsd”

- &GT;打开后,即:http://schemas.opengis.net/ows/1.0.0/owsGetCapabilities.xsd

您会发现这种复杂的类型定义:

<complexType name="GetCapabilitiesType">
<annotation>
     <documentation>
         XML encoded GetCapabilities operation request. This operation 
         allows clients to retrieve service metadata about a specific service instance.
         In this XML encoding, no "request" parameter is included, since the element name 
         specifies the specific operation. This base type shall be extended by each specific 
         OWS to include the additional required "service" attribute, with the correct value for that OWS. 
     </documentation>
</annotation>
<sequence>
     <element name="AcceptVersions" type="ows:AcceptVersionsType" minOccurs="0">
         <annotation>
             <documentation>When omitted, server shall return latest supported version. 
             </documentation>
         </annotation>
     </element>
     <element name="Sections" type="ows:SectionsType" minOccurs="0">
         <annotation>
             <documentation>
                 When omitted or not supported by server, 
                 server shall return complete service metadata (Capabilities) document. 
             </documentation>
         </annotation>
     </element>
     <element name="AcceptFormats" type="ows:AcceptFormatsType" minOccurs="0">
         <annotation>
             <documentation>
                 When omitted or not supported by server, server shall return service metadata 
                 document using the MIME type "text/xml". 
             </documentation>
         </annotation>
     </element>
 </sequence>
<attribute name="updateSequence" type="ows:UpdateSequenceType" use="optional">
     <annotation>
         <documentation>
             When omitted or not supported by server, 
             server shall return latest complete service 
             metadata document. 
         </documentation>
     </annotation>
</attribute>
</complexType>

现在这个GetCapabilitiesType具有元素/属性:
name =“AcceptVersions”的type =“ows:AcceptVersionsType”和minOccurs =“0”ie即可为null name =“Sections”类型=“ows:SectionsType”和minOccurs =“0”即ie可以为null name =“AcceptFormats”的类型=“ows:AcceptFormatsType”和minOccurs =“0”即ie可以为null type =“updateSequence”,类型=“ows:UpdateSequenceType”,它是可选的 - &gt; use =“optional”

在哪里可以找到这些属性定义?
- &gt;在同一页面上你有: AcceptVersionsType为:

<complexType name="AcceptVersionsType">
 <annotation>
 <documentation>
  Prioritized sequence of one or more specification versions accepted by client, with preferred versions listed first. See Version negotiation subclause for more information.     
 </documentation>
 </annotation>
 <sequence>
  <element name="Version" type="ows:VersionType" maxOccurs="unbounded"/>
 </sequence>
</complexType>


所以AcceptVersionsType有一个类型的元素:VersionType可以在xsd owsOperationsMetadata.xsd(在这个页面的同一个链接上)找到,在它上面你有xsd:owsCommon.xsd这是这是找到VersionType的地方     即http://schemas.opengis.net/ows/1.0.0/owsCommon.xsd

<simpleType name="VersionType">
  <annotation>
    <documentation>Specification version for OWS operation. The string value shall contain one x.y.z "version" value (e.g., "2.1.3"). A version number shall contain three non-negative integers separated by decimal points, in the form "x.y.z". The integers y and z shall not exceed 99. Each version shall be for the Implementation Specification (document) and the associated XML Schemas to which requested operations will conform. An Implementation Specification version normally specifies XML Schemas against which an XML encoded operation response must conform and should be validated. See Version negotiation subclause for more information. </documentation>
  </annotation>
  <restriction base="string"/>
</simpleType>

和sectionsType为:

<complexType name="SectionsType">
 <annotation>
   <documentation>
    Unordered list of zero or more names of requested sections in complete service metadata document. Each Section value shall contain an allowed section name as specified by each OWS specification. See Sections parameter subclause for more information.            
   </documentation>
 </annotation>
 <sequence>
    <element name="Section" type="string" minOccurs="0" maxOccurs="unbounded"/>
 </sequence>
</complexType>

(SectionsType有一个简单类型为String的元素)

AcceptFormatsType是:

<complexType name="AcceptFormatsType">
 <annotation>
   <documentation>
    Prioritized sequence of zero or more GetCapabilities operation response formats desired by client, with preferred formats listed first. Each response format shall be identified by its MIME type. See AcceptFormats parameter use subclause for more information. 
   </documentation>
 </annotation>
 <sequence>
  <element name="OutputFormat" type="ows:MimeType" minOccurs="0" maxOccurs="unbounded"/>
  </sequence>
</complexType>

(AcceptFormatsType有一个MimeType类型的元素,它与VersionType相同,即:http://schemas.opengis.net/ows/1.0.0/owsCommon.xsd

<simpleType name="MimeType">
  <annotation>
    <documentation>XML encoded identifier of a standard MIME type, possibly a parameterized MIME type. </documentation>
  </annotation>
  <restriction base="string">
    <pattern value="(application|audio|image|text|video|message|multipart|model)/.+(;s*.+=.+)*"/>
  </restriction>
</simpleType>

和UpdateSequenceType是(它是一个简单类型而不是复杂类型):

 <simpleType name="UpdateSequenceType">
 <annotation>
  <documentation>
   Service metadata document version, having values that are "increased" whenever any change is made in service metadata document. Values are selected by each server, and are always opaque to clients. See updateSequence parameter use subclause for more information.     
   </documentation>
  </annotation>
 <restriction base="string"/>
 </simpleType>

(UpdateSequenceType是一种简单类型)

现在我希望如何更清楚地阅读架构。 现在复杂类型表示与简单类型不同的对象(例如:int)。如果您有复杂类型,并且使用的是ksoap2,则必须在实现kvmSerializable(ksoap2序列化接口)的类(对象)中创建本地表示。

现在,您可以阅读我的答案,了解如何执行此操作: Link1link2link3。我写了一些细节,可以帮助您了解如何开始编码。

我今天不会在我的电脑上。希望这会有所帮助,让我知道wt我说的任何东西都是暧昧的。

答案 1 :(得分:0)

通常情况下,根据我对ksoap2的一点经验,你会做这样的事情。

SoapObject request = new SoapObject("http://www.webserviceX.NET", "GetCitiesByCountry");
String soapAction = "http://www.webserviceX.NET/GetCitiesByCountry";

request.addProperty("CountryName", "india");
SoapSerializationEnvelope envelope = new SoapSerializationEnvelope(SoapEnvelope.VER11);
envelope.bodyOut = request;
envelope.dotNet = true;

HttpTransport ht = new HttpTransport("http://www.webservicex.net/globalweather.asmx");
ht.debug = true;
//System.err.println( ht.requestDump );

ht.call(soapAction,envelope);
System.out.println("####################: " +envelope.getResponse());
//SoapObject result = (SoapObject)envelope.getResponse();

所以基本上你应该拿你的soapObject并调用addProperty()。