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

标签 java android web-services jaxb ksoap2

我完全不熟悉 Web Feature Service (WFS)但我想用 ksoap2-android 构建一个 Android 应用程序在通过 WFS 发布其数据的 API 之上。我想从 API 请求数据,将它们传递给 bounding box 参数以限制将返回的数据。

问题:

  • 如何将 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 的启发。 .我完全不确定namespacemethodNameurl 是否正确!

// 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 日


我设法走得更远,我几乎找到了似乎是解决方案的东西。我找到了 schema definitions对于 XML 请求中使用的那些命名空间,并将它们链接到我的项目。这使我能够为请求组装对象。

// 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 日


这是 error message from Eclipse当您尝试为 Android 编译 JAXBElement 时。

最佳答案

@JJD 我看到你在 here 给我留言了
我一会儿要开会,但我看了你的问题,很乐意尽可能提供帮助。我发现您在阅读架构定义时遇到了问题。你所拥有的这个 ws 定义被一个链接在另一个里面,这就是为什么你在阅读它时感到困惑:

如果你继续: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”

--> 打开之后,即: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 有元素/属性:
type="ows:AcceptVersionsType"和 minOccurs="0"的 name="AcceptVersions"即可以为空 name="Sections"of type="ows:SectionsType"and minOccurs="0"即可以为空 type="ows:AcceptFormatsType"的 name="AcceptFormats"和 minOccurs="0"即可以为空 type="ows:UpdateSequenceType"的 name="updateSequence"并且它是可选的 -->use="optional"

在哪里可以找到这些属性定义?
--> 在同一页面上,您有: 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 序列化接口(interface))的类(对象)中创建本地表示。

现在,您可以阅读我的回答以了解如何在 : Link1 , link2 , link3 .我写了一些细节,可以帮助您了解如何开始编码。

我今天不会在我的电脑上。希望这会有所帮助,如果我说的任何内容含糊不清,请告诉我。

关于java - 如何在 Android 中通过 POST 请求查询 Web 服务?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9237082/

相关文章:

c# - WCF 服务健康监控

c# - 从列表中删除 dto 时要发回的内容

java - 如何在java中使用android 2.2 sdk播放.avi视频?

android - 点击FCM通知消息时如何获取消息正文?

SAP 项目的 Web 服务粒度?

java - 复制字符串数组并删除空字符串

Android CollapsingToolbarLayout 与自定义 View

Java 等同于 .NET 的 DateTime.Parse?

java - 取消从 InputStream 的读取

java - SonarQube 与 Jenkins