Форум Flasher.ru

Форум Flasher.ru (http://www.flasher.ru/forum/index.php)
-   Flex (http://www.flasher.ru/forum/forumdisplay.php?f=84)
-   -   работа с WebService (http://www.flasher.ru/forum/showthread.php?t=119010)

jerzy 10.12.2008 02:11

работа с WebService
 
Доброго дня

я новайс во Флексе, посему извините за быть может дурной вопрос
суть вопроса такова - как более оптимально передавать объекты на вебсервис и обратно? Простые типы, вроде интов и стрингов туда-сюда ходят нормально :) а вот какой-то класс чуток посложнее вызывает у меня трудности.
Сразу пример

есть класс
Код:

package my.entity;

import java.io.Serializable;

public class Unit implements Serializable {

    private int id;
    private int type;
    private String name;

    public Unit() {
    }

    public Unit(int type, String name) {
        this.type = type;
        this.name = name;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public int getType() {
        return type;
    }

    public void setType(int type) {
        this.type = type;
    }

    @Override
    public String toString() {
        return "Unit: " + ":" + type + ":" + name;
    }
}

На стороне клиента у меня есть такой же класс.
если я рассматриваю результат operation, как xml, то получаю следующую:
Код:

<getTurnResponse xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns="http://my/xsd">
  <return type="my.entity.Unit">
    <name>unit1</name>
    <type>1</type>
  </return>
</getTurnResponse>

т.е. вроде всё верно. Но автоматически преобразовать xml в класс не получается. Руками парсить и создавать объекты - можно, но как-то грустно. А если у меня объекты будут более сложными?

И как с клиента на сервер передавать? Тоже переводить руками в xml, а на стороне сервера собирать объект? Думаю, что есть нормальные решения, однако в хелпе не нашел и первая попытка прогуглить тоже успеха не принесла

PS. Впрочем распарсить сие тоже не получается. Как в хелпе - не работает

Код AS3:

var result:XML = XML(event.result);
for each (var item:XML in result.elements()){
trace("item:" + item.type + ":" + item.name);
}


7thsky™ 10.12.2008 03:33

Для класс мапинга класс надо регистрировать в mx.rpc.xml.SchemaTypeRegistry (смотреть >> тут << ). Потом ваш VO объект должен содержать либо public свойства, либо get | set свойства, а не getter/setter методы.

Что то типа
Код AS3:

public class Unit {
    public var id:int;
    public var type:int;
    public var name:String;
}

Потом, если Вы пользуетесь Flex Builder'ом, то начиная с 3 версии, у него есть генератор набора классов для клиента под WSDL вебсервиса.
Menu - > Data - > Import Web Service. Один раз просматрев что генерируется можно лучше понять как именно флекс работает с вебсервисами.

jerzy 11.12.2008 02:29

Супер! По идее это отличная возможность решения проблемы, но...
после автогенерации классов из wsdl я пытаюсь дернуть один из методов и получаю ошибку
Код:

TypeError: Error #1090: XML parser failure: element is malformed.
        at mx.rpc.soap::SOAPEncoder/encodeOperationAsDocumentLiteral()[E:\dev\3.0.x\frameworks\projects\rpc\src\mx\rpc\soap\SOAPEncoder.as:379]
        at mx.rpc.soap::SOAPEncoder/encodeBody()[E:\dev\3.0.x\frameworks\projects\rpc\src\mx\rpc\soap\SOAPEncoder.as:322]
        at mx.rpc.soap::SOAPEncoder/encodeEnvelope()[E:\dev\3.0.x\frameworks\projects\rpc\src\mx\rpc\soap\SOAPEncoder.as:188]
        at mx.rpc.soap::SOAPEncoder/encodeRequest()[E:\dev\3.0.x\frameworks\projects\rpc\src\mx\rpc\soap\SOAPEncoder.as:158]
        at webservices::BaseWS/call()[D:\Work\Flex\TestWS\src\webservices\BaseWS.as:225]
        at webservices::BaseWS/getTestUnit()[D:\Work\Flex\TestWS\src\webservices\BaseWS.as:177]
        at webservices::WS/getTestUnit()[D:\Work\Flex\TestWS\src\webservices\WS.as:88]
        at webservices::WS/getTestUnit_send()[D:\Work\Flex\TestWS\src\webservices\WS.as:98]
        at testWS/__myButton_click()[D:\Work\Flex\TestWS\src\testWS.mxml:3]

сам апликейшн, который инициирует запрос выглядит так:
Код:

<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" layout="absolute" xmlns:srv="webservices.*">
        <mx:Button id="myButton" label="Call operation" click="myService.getTestUnit_send()" />
        <srv:WS id="myService">
    <srv:login_request_var>
                  <srv:Login_request username="7thsky" />
    </srv:login_request_var>
  </srv:WS>
</mx:Application>

а на стороне сервиса живет сам вебсервис и wsdl, который был сгенерен нетбинсом.
Код:

public class WS {
    public boolean login(String username){
        log.error("login:" + username);
        return true;
    }
}

я в аппликейшне посылаю не правильный юзернейм или дело в чем-то другом? :)

7thsky™ 11.12.2008 08:00

еще б знать что такое WS и что конкретно делает метод getTestUnit () да и посмотреть что приходит и уходит с сервера.

А так только гадать.

jerzy 11.12.2008 13:01

Вложений: 1
сделаем поправку на позднее время. Повторил перегенерацию кода в клиенте - ошибка пропала. Но всё равно не всё ладно в датском королевстве.

теперь в евенте сидит объект правильного типа (ура!), но пустой ([object Unit] : NaN:NaN:null) :(

я приаттачил сырцы в архив, чтоб не делать огромный пост тут и не было угадайки, надеюсь, получится в них глянуть?

!.zip - там два серверных класса, WS (вебсервис) и сам Unit, а так же сгенеренный wsdl
и то, что сгенерил ФлексБилдер на стороне клиента

7thsky™ 13.12.2008 12:49

в архиве нету описания xsd твоего типа Unit (XSD линкованный: xmlns:ns0="http://entity.my/xsd").
Потом стоит все таки посмотреть что именно между сервером и флэшем проходит (в каком нить снифере например)

А так вроде все правильно.

З.Ы. А генератор адобе подравили в 2.0.1 был такой ужасный.
З.Ы. Если клиент только на флэше, может стоит посмотреть в сторону AMF (там и класс маппинг проще, и все что нужно уже для этого встроенно в флэш плеер)
AMF, OpenAMF, BlazeDS

jerzy 14.12.2008 21:48

Цитата:

Сообщение от 7thsky™ (Сообщение 783439)
в архиве нету описания xsd твоего типа Unit (XSD линкованный: xmlns:ns0="http://entity.my/xsd").

на самом деле есть в секции <wsdl:types>
вот:
Код:

<xs:schema xmlns:ax21="http://entity.my/xsd" attributeFormDefault="qualified" elementFormDefault="qualified" targetNamespace="http://entity.my/xsd">
            <xs:complexType name="Unit">
                <xs:sequence>
                    <xs:element minOccurs="0" name="id" type="xs:int"/>
                    <xs:element minOccurs="0" name="name" nillable="true" type="xs:string"/>
                    <xs:element minOccurs="0" name="type" type="xs:int"/>
                </xs:sequence>
            </xs:complexType>
        </xs:schema>

но не в виде отдельной схемы. Честно говоря, я в вебсервисах не хавец, но мне кажется, что так и надо - все в одной xml-ке записано


Цитата:

Потом стоит все таки посмотреть что именно между сервером и флэшем проходит (в каком нить снифере например)
да, тоже вариант - посмотрю

Цитата:

А так вроде все правильно.

З.Ы. А генератор адобе подравили в 2.0.1 был такой ужасный.
З.Ы. Если клиент только на флэше, может стоит посмотреть в сторону AMF (там и класс маппинг проще, и все что нужно уже для этого встроенно в флэш плеер)
AMF, OpenAMF, BlazeDS
про генератор - ну, значит мне повезло, что не взялся за него раньше :))

По правде говоря, я к вебсервисам вышел после того, как попробовал HTTPService, но они чем-то мне не понравились... Потом я взялся за OpenAMF, но там погряз окончательно... мало документации, не понятная, туториала не нашел... короче, забросил и остались мне вебсервисы.
Жаль, что я не наткнулся на BlazeDS раньше. Спасибо за подсказку.

PS. Наверное вскорости стоит ожидать вопросов по теме BlazeDS :D

PPS. И, для закрытия гештальта, в каких случаях стоит использовать вебсервисы, а в каких можно обойтись маппингом, который предоставляет тот же BlazeDS?
Если у меня несколько разных приложений работает с сервером (типа сайт, удаленный клиент), то лучше вебсервис? Или по другому критерию нужность определяется?

7thsky™ 15.12.2008 01:30

Проглядел я описание :)

Насчет что лучше:
(Я тоже не большой спец) Если использовать несколько клиентов, то я б использовал более общий протокол - типа SOAP, а не AMF.

А посмотреть результат можно впринципе и без снифера, поставив breakpoint в result handler'e и пробежавшись по стэку вызовов методов.

З.Ы. Я обычно таким образом вызываю методы Вебсервисов

Код AS3:

var wsInstance:WS = new WS ();
var token:AsyncToken = wsInstance.getTestUnit();
token.addResponder = new mx.rpc.Responder (
        wsGetTestUnitResultHandler, wsGetTestUnitFaultHandler);
 
 
function wsGetTestUnitResultHandler (evt:ResultEvent):void {}
function wsGetTestUnitFaultHandler (evt:FaultEvent):void {}



Часовой пояс GMT +4, время: 16:51.

Copyright © 1999-2008 Flasher.ru. All rights reserved.
Работает на vBulletin®. Copyright ©2000 - 2026, Jelsoft Enterprises Ltd. Перевод: zCarot
Администрация сайта не несёт ответственности за любую предоставленную посетителями информацию. Подробнее см. Правила.