Check alle échte Black Friday-deals Ook zo moe van nepaanbiedingen? Wij laten alleen échte deals zien
Toon posts:

[Java] Objectmodel voor webservices op client/server

Pagina: 1
Acties:

Verwijderd

Topicstarter
Hallo mensen,

ik ben momenteel bezig met een project waarbij er gecommuniceerd moet gaan worden tussen een client en een server met behulp van webservices. Het is de bedoeling dat de server informatie registreert en bijhoudt over verschillende zaken, met daaraan gekoppelde data zoals status, deelnemers etc... Hier bovenop komt de client, die de gegevens weergeeft in een webinterface (JSP).

De objecten met data worden dus eerst geserialiseerd op de server, verstuurd per webservice, en vervolgens gedeserialiseerd in de client. De objecten in de client kunnen uiteraard niet direct "onderliggende" objecten in de kernel aansturen, omdat de client gescheiden is. Het probleem hierbij is; hoe hoe worden mutaties, die worden uitgevoerd in de client, afgehandeld in de server? Als er op de client mutaties worden uitgevoerd op het object, dan moeten deze uiteindelijk ook worden doorgevoerd in de server.

De huidige opzet is als volgt;
Om operaties die in de client worden uitgevoerd op de objecten af te vangen, worden er dus alleen waarden in de objecten gezet, en vervolgens wordt het object, met de nieuwe waarden, terug gestuurd naar de server. De server bekijkt per attribuut in het object of het attribuut is gewijzigd, en update dan vervolgens de attributen op de server (wegschrijven naar een DB bijv.) Dit is echter erg omslachtig omdat alle attributen moeten worden gecontroleerd, en ook de attributen van attributen. (hiermee bedoel ik onderliggende objecten, zoals bijvoorbeeld deelnemers bij een zaak, hieronder misschien weer de rol die zij hebben, etc...)

Een andere optie zou kunnen zijn dat op de client elke methode een onderliggende webservice naar de server aanroept, zodat de bewerking gelijk wordt uitgevoerd, maar dit lijkt me erg intensief wat netwerkverkeer (en vertraging) betreft.

Ik neem aan dat er eerder mensen tegen soortgelijke problemen aan zijn gelopen, en dat er goede (betere dan de huidige) oplossingen beschikbaar zijn. Iemand die hier ideeen over heeft? :)

  • JKVA
  • Registratie: Januari 2004
  • Niet online

JKVA

Design-by-buzzword fanatic

Web services zijn doorgaans coarse grained services. Dit in tegenstellingen tot AJAX "endpoints", waarbij veel meer chattiness optreedt.

Mijn aanpak is doorgaans: Gebruik web services op business transactie niveau, dus niet een web services call voor elke tussenstap, maar alleen de laatste stap verstuur je naar de web service.

Jouw probleem met validaties snap ik niet helemaal. Dat staat volgens mij los van de techniek web services. Maar goed, een groot deel van de validaties (structuur, syntax multipliciteit) kun je al in je WSDL afvangen door een schema te maken en daarin een aantal checks te maken. De rest moet je gewoon uitprogrammeren. Dat is onderdeel van je service interface contract dus moet gewoon op de server gebeuren.

Maar, om netwerkverkeer en responsetijden te optimaliseren, kun je natuurlijk validaties dupliceren op je client. Bij simpele validaties is dat naar mijn idee geen probleem.

Of veel of weinig web service calls slim is, hangt van teveel factoren af om hier antwoord op te geven. je moet een afweging maken tussen responsetijden, netwerkverkeer, serverbelasting, onderhoudbaarheid, security, etc...

Fat Pizza's pizza, they are big and they are cheezy


Verwijderd

Topicstarter
Ik zal even een voorbeeldje geven. Je hebt bijvoorbeeld een klasse Zaak, met een aantal attributen. Een instantie van de klasse Zaak representeert een record uit een database. Wijzigingen aan het object moeten dus ook worden doorgevoerd in de database.

code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
public class Zaak {

    private int id;
    private String naam;

    public Zaak(int id, String naam) {
         this.id = id;
         this.naam = naam;
    }

    public void setNaam(String naam) {
         this.naam = naam;
    }
}


Hoe implementeer je deze klasse op de server en op de client? Stel dat je setNaam() aanroept op de client, hoe wordt dit dan doorgevoerd naar de server?

De klassen kunnen op de client en de server dezelfde interface hebben, maar een andere implementatie. Op de client verandert alleen een interne waarde in de klasse, deze wordt terug gestuurd via de WS, en op de server wordt de wijziging door de server variant van de klasse gelijk weg geschreven naar de onderliggende database.

Of de klassen zijn beide hetzelfde, en dus er wordt alleen intern een waarde veranderd, en de klasse functioneert eigenlijk alleen als datacontainer. Deze wordt via de WS naar de server gestuurd en vervolgens kijkt een andere hulpklasse, die alleen aanwezig is op de server, of er iets is gewijzigd aan de Zaak, en schrijft indien nodig de wijzigingen naar de database.


De vraag is dus eigenlijk, gebruik ik dezelfde implementatie voor de klasse Zaak op zowel de server als de client, waarbij de klasse dus geen aanroepen kan doen naar een database oid om de wijzigingen weg te schrijven, of maak je twee afzonderlijke implementaties voor de klasse, zodat de client Zaak anders is dan de server Zaak?

Dit zijn zo de oplossingen die ik kan bedenken, maar ik vind ze beide eigenlijk niet erg mooi. :?

  • whoami
  • Registratie: December 2000
  • Laatst online: 22:01
een method als 'setNaam' moet zeker geen web-method zijn. Als je dit wel doet, dan krijg je een chatty model, waar JKVA al over sprak. Je moet er idd voor zorgen dat je een coarse grained API creeërt, en geen fine grained.
Enkel de 'SaveZaak' method bv zou een web-method moeten zijn.

Wat gebeurt er bv:
Je hebt een webmethod 'GetZaak' die je een 'Zaak' object teruggeeft. Dit object wordt op de server (door de webservice) gecreeërd en opgevuld met gegevens uit de DB, en wordt verstuurd naar de client. Dit betekent dus dat je er moet voor zorgen dat je 'Zaak' object serializeerbaar is. Het object moet nl over het netwerk kunnen verstuurd worden.

Aan de clientkant krijg je dus een 'kopie' van dat Zaak object. Daar kan je vanalles mee doen (bv de naam veranderen), en dan stuur je het terug naar de webservice om de wijzigingen te bewaren (De SaveZaak webmethod bv).

Hoe het in Java technisch precies geregeld is , weet ik niet. In .NET is het zo dat je bv een webreference maakt naar een webservice, en de nodige classes laat genereren die nodig zijn om die webservice te gebruiken. (Op basis van WDSL).

https://fgheysels.github.io/


Verwijderd

Topicstarter
Het is inderdaad ook niet de bedoeling dat setNaam() een aparte WS functie krijgt, maar ik wil weten hoe de (op de client) gewijzigde data in het Zaak object wordt verwerkt in de server.

Zoals jij het zegt, wordt er dus een kopie van het Zaak-object op de server naar de client gestuurd. De client voert er vervolgens een aantal bewerkingen op uit, en stuurt het object terug naar de server. Dan ontkom je er dus niet aan dat er een andere hulpklasse bij moet komen die dan het van de client ontvangen Zaak object uitleest op de server, en de wijzigingen doorvoert?

[ Voor 2% gewijzigd door Verwijderd op 05-02-2008 14:41 . Reden: typfout ]


  • NetForce1
  • Registratie: November 2001
  • Laatst online: 20-11 09:15

NetForce1

(inspiratie == 0) -> true

Je kunt op de server ook mbv reflection kijken wat er precies gewijzigd is, scheelt weer bergen fout-gevoelige copy-paste code. Wellicht kan de BeanInspector hierbij ook nog van pas komen ipv alles zelf met reflection te doen.

De wereld ligt aan je voeten. Je moet alleen diep genoeg willen bukken...
"Wie geen fouten maakt maakt meestal niets!"


  • whoami
  • Registratie: December 2000
  • Laatst online: 22:01
Verwijderd schreef op dinsdag 05 februari 2008 @ 14:40:

Zoals jij het zegt, wordt er dus een kopie van het Zaak-object op de server naar de client gestuurd. De client voert er vervolgens een aantal bewerkingen op uit, en stuurt het object terug naar de server. Dan ontkom je er dus niet aan dat er een andere hulpklasse bij moet komen die dan het van de client ontvangen Zaak object uitleest op de server, en de wijzigingen doorvoert?
:? Waarom ?

code:
1
2
3
4
5
6
[WebMethod]
public Zaak GetZaak( int zaakid )
{
    // haal nodige gegevens uit DB , en creeër een Zaak object.
     return new Zaak ( ... );
}


Je client krijgt dan dat Zaak object (wat op zich niet veel meer zal zijn dan een Data Transfer Object).
Daarna stuur je dat zelfde Zaak object naar je webservice 'SaveZaak'
code:
1
2
3
4
5
[WebMethod]
public void SaveZaak( Zaak zaak )
{
   // sla de wijzigingen op in de DB.
}


Waarom denk je dat je nog een 'hulpobject' nodig hebt, en wat moet dat hulpobject wel doen ?
Op de client moet je er voor zorgen dat je een proxy hebt naar je webservice en dat je DTO's ook gekend zijn.

https://fgheysels.github.io/


  • Vaudtje
  • Registratie: April 2002
  • Niet online
Zoals JKVA en whoami al aangeven is je huidige oplossing inderdaad het beste, omdat die coarse-grained is.
Om te voorkomen dat je te veel attributen en members moet doorlopen bij het opslaan, zou je meerdere service methods voor een object kunnen definieren, die verschillende aspecten van de object graaf opslaan en de rest negeren.
Je krijgt dan een saveZaak() die alleen de Zaak attributen verwerkt zonder naar de members te kijken, en een updateZaakKlanten() die de relaties administreert.
offtopic:
Begrijp ik goed dat je een webservice hebt die aangeroepen wordt vanuit een webserver, die op zijn beurt de client bedient? Draait de webserver dan op de client machine?

In deeze zin staan drie fauten


Verwijderd

Topicstarter
Oke, het is me duidelijk :)

Ik maakte even een vergissing door te denken dat er een hulpklasse moest worden toegevoegd die zou kijken welke wijzigingen er waren doorgevoerd in het object, zodat deze konden worden doorgevoerd naar de database, maar dit wordt uiteraard al in de functie SaveZaak() afgehandeld :X

Verwijderd

Heb je een email/msn adres, ik ben toevallig bezig geweest met een dergelijk projectje, kan je wel wat laten zien. DM me maar als je behoefte hebt :)

Eeeh, dat zou de discussie uit dit topic verplaatsen en dat zou zonde zijn dus liever niet

[ Voor 25% gewijzigd door een moderator op 05-02-2008 15:48 ]


  • JKVA
  • Registratie: Januari 2004
  • Niet online

JKVA

Design-by-buzzword fanatic

Verwijderd schreef op dinsdag 05 februari 2008 @ 14:59:
Oke, het is me duidelijk :)

Ik maakte even een vergissing door te denken dat er een hulpklasse moest worden toegevoegd die zou kijken welke wijzigingen er waren doorgevoerd in het object, zodat deze konden worden doorgevoerd naar de database, maar dit wordt uiteraard al in de functie SaveZaak() afgehandeld :X
Ik maak me doorgaans niet eens druk om welke properties gewijzigd zijn. Je wijzigt een stel properties in een transactie. Die transactie commit je dan in één keer. Als je bij elke wijziging een save actie doet, kan je object ook in invalide toestanden terecht komen terwijl je opslaat, bijvoorbeeld wanneer 2 velden een relatie hebben, zoals een lijst met personen en een integer "aantalPersonen".

Web Services volgen een soort pass by copy principe, in plaats van pass by reference. Dat is ook goed, want dat maakt je code veel voorspelbaarder.

Fat Pizza's pizza, they are big and they are cheezy


  • Alarmnummer
  • Registratie: Juli 2001
  • Laatst online: 09-07-2024

Alarmnummer

-= Tja =-

Waarom kies je voor deze aanpak? Is dit een must? Layers zijn meestal goed.. tiers zijn vaak bad: je zit altijd met het overpompen van data en dat brengt veel onnodige complexiteit met zich mee. Persoonlijk heb ik liever alle lagen op een (vm)machine en als ik wil schalen kan ik meerdere machines parallel naast elkaar zetten.

Verder moet je heel goed oppassen met een tight coupling tussen het domein model voor de business logic en het domain model op de view als je gebruik maakt van tiers aangezien je dan juist meer stabiliteit wenst.

[ Voor 49% gewijzigd door Alarmnummer op 06-02-2008 15:53 ]

Pagina: 1