Как запросить веб-сервис через POST-запрос в Android? - PullRequest
1 голос
/ 11 февраля 2012

Я совершенно новичок в Web Feature Service (WFS) , но я хочу создать приложение Android с ksoap2-android поверх API, публикующего свои данные через WFS. Я хотел бы запросить данные у API, передав им параметр ограничивающий прямоугольник , чтобы ограничить данные, которые будут возвращены.

Вопросы:

  • Как поместить объект GetFeature в конверт SOAP?
  • Как я могу использовать JAXBElement на клиенте Android? См. Редактирование от 15 марта 2012 г.

Вот несколько ссылок на API, которые могут помочь понять их формат.

Пример: PFS-запрос GetFeature WFS-1.1, 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, который я придумал. В основном это вдохновлено примерами из вики ksoap2-android . Я абсолютно не уверен , правильны ли пространство имен , 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;
    }
}

РЕДАКТИРОВАТЬ: 15 марта 2012 г.


Мне удалось продвинуться дальше, и я почти достиг того, что кажется решением. Я нашел определения схемы для этих пространств имен, используемых в запросе 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 содержится в базовой библиотеке (javax.xml.bind.JAXBElement), которую Android отказывается использовать. Незначительные проблемы изложены в комментариях и TODO.

РЕДАКТИРОВАТЬ: 27 апреля 2012 г.


Когда я читаю этот пост Я думаю, что нечто подобное может относиться к моей проблеме Я еще не пробовал.

РЕДАКТИРОВАТЬ: 09 мая 2012 г.


Вот сообщение об ошибке от Eclipse , когда вы пытаетесь скомпилировать JAXBElement для Android.

Ответы [ 2 ]

2 голосов
/ 12 февраля 2012

@ JJD я вижу, вы оставили мне сообщение в здесь
У меня есть встреча через некоторое время, но я взглянул на ваш вопрос и был бы рад помочь как можно больше.Я вижу, у вас есть проблемы с чтением определения схемы.у вас есть это определение ws, связанное одно внутри другого, поэтому оно вас смутило, читая его:

Если вы продолжите: http://schemas.opengis.net/wfs/1.1.0/wfs.xsd

, возьмите метод "GetCapabilities" и давайте прочитаем его вопределение веб-службы:

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 имеет элементы / атрибуты:
name = "AcceptVersions" типа = "ows: AcceptVersionsType "и minOccurs =" 0 ", т. Е. Могут иметь значение null name =" Sections "типа =" ows: SectionsType "и minOccurs = "0", т. е. может иметь значение null name = "AcceptFormats" типа = "ows: AcceptFormatsType" и minOccurs = "0", т. е. может иметь значение null name = "updateSequence" типа = "ows: UpdateSequenceType", и это необязательно-> use = "необязательный"

Где найти определения этих атрибутов?
-> на этой же странице у вас есть: AcceptVersionsType is:

<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 thisэто где 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>

, а sectionType:

<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).

Теперь вы можете прочитать мои ответы, чтобы узнать, каксделать это на: Link1 , link2 , link3 .Я написал некоторые детали, которые помогут вам понять, как начать кодирование.

Я не буду на моем компьютере в течение дня.Надеюсь, что это поможет, дайте мне знать, если что-нибудь из того, что я сказал, неоднозначно.

0 голосов
/ 12 февраля 2012

Обычно, и из того небольшого опыта, который у меня есть с 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 ().

...