2008 06 Java Microedition – metody integracji aplikacji [Inzynieria Oprogramowania]


Inżynieria
oprogramowania
Java Microedition
 metody integracji aplikacji
Albert Wachowicz
plikacje Java Microedition (konfiguracji Jednym z lepszych zestawień danych technicz-
CLDC) działające na urządzeniach przeno- nych urządzeń mobilnych różnych producentów
Aśnych mają zazwyczaj ograniczone zaso- jest strona J2MEPolish.
by sprzętowe. W większości przypadków limitowa- Kolejnym ważnym aspektem jest profil urzą-
na pamięć oraz wolne procesory na urządzeniach dzenia Mobile Information Device Profile w skró-
powodują, że pewne zadania są mało wydajne lub
niemożliwe do zrealizowania. Rozwiązaniem tego
Listing 1. Przykładowa metoda wysyłająca
problemu może być przeniesienie części funkcjo-
wiadomość poprzez gniazdo
nalności aplikacji na stronę serwera. W ten sposób
realizuje się ubogiego klienta, który wymaga mniej void sendSocketMsg(String destAddr, String msg) {
zasobów przy zakładanej funkcjonalności. Nato- try {
miast serwer przejmuje wymagające większych //utworzenie gniazda
zasobów zadania i zwraca do aplikacji klienckiej SocketConnection client =
tylko rezultaty swojej pracy. (SocketConnection)
Niniejszy artykuł skupi się na sposobach in- Connector.open("socket://"
tegracji aplikacji klienta JME z aplikacją serwera. + destAddr + ":3000");
Zostanie zaprezentowany krótki przegląd metod
za pomocą których można skomunikować klien- //otwarcie strumienii wejscia/wyjscia
ta z serwerem. InputStream is = client.openInputStr
Gruntownie zostaną opisane wybrane mecha- eam();
nizmy integracji, które obecnie są najczęściej sto- OutputStream os = client.openOutputSt
sowane. Na koniec zostanie przedstawiona ocena ream();
wybranych metod w odniesieniu do wszechstron-
nego zastosowania. // wysłanie wiadomosci doserwera
os.write(msg.getBytes());
Uwagi na temat technologii JME os.write('\n');
W technologii JME paczki z bibliotekami dostępne
są bezpośrednio w maszynie wirtualnej KVM (Kilo- // odczytanie odpowiedzi (dla
byte Virtual Machine) urządzenia dzięki czemu pro- przykladu do znaku konca
gramista nie musi martwić się o ich dostępność. Z linii \n lub gdy serwer
drugiej strony istnieją rozwiązania, które wymagają zamknie polaczenie)
dołączenia odpowiedniej biblioteki zawartej w ar- int c = 0;
chiwum jar. Wiąże się to niestety ze wzrostem roz- StringBuffer sb = new StringBuffer();
miaru (archiwum jar) aplikacji co ma istotne zna- while ((c = is.read()) != -1 && (c!='\
czenia w przypadku limitów maksymalnej wielko- n')) {
ści narzuconej przez producentów. sb.append((char)c);
Zagadnienie to nie stanowi jednakże tematu }
niniejszego artykułu. Zainteresowanym polecam
strony producentów urządzeń, gdzie w większości System.out.println("[Serwer]"+
przypadków tego rodzaju informacje są dostępne. sb.toString());
//analiza odpowiedzi...
Albert Wachowicz pracuje na stanowisku Software
// zamkniecie strumieni oraz
Specialist w BLStream wchodzącym w skład Grupy
polaczenia
BLStream. Grupa BLStream powstała by efektywniej
is.close();
wykorzystywać potencjał dwóch, szybko rozwijają-
os.close();
cych się producentów oprogramowania  BLStream
client.close();
i Gamelion. Firmy wchodzące w skład grupy specja-
lizują się w wytwarzaniu oprogramowania dla klien- } catch (IOException ex) {
tów korporacyjnych, w rozwiązaniach mobilnych oraz ex.printStackTrace();
produkcji i testowaniu gier.
}
Kontakt z autorem: albert.wachowicz@gmail.com
}
58
www.sdjournal.org
Software Developer s Journal 6/2008
Java Microedition
cie MIDP oraz konfiguracja Connected Limited Device Con- " Komunikacja niskopoziomowa  UDP, TCP, TLS(SSL);
figuration CLDC. Określa się w nich zbiór interfejsów i klas " HTTP/HTTPS;
dostępnych w danej KVM. Aktualnie dominującym profilem " RMI  J2MEPolishRMI, implementacja RMI bazująca na
jest MIDP 2.0 w połączeniu z konfiguracją CLDC 1.1 (lub gniazdach;
1.0). Jednakże istnieją także urządzenia określane mianem " XML-RPC  kXMLRPC, J2MEPolishRPC;
wersji MIDP 1.0. W artykule zostanie zaznaczone od któ- " Web Services  kSOAP[5], klient WebServices w NetBe-
rej wersji profilu dostępny jest dany mechanizm jeśli bę- ans, JSR-172;
dzie to istotne. " WMA  SMS/MMS;
" SIP;
Spis metod integracyjnych " SyncML  kSync, implementacja SyncML;
Biorąc pod uwagę ogólne standardy komunikacji siecio- " Peer2Peer  JXTA;
wej w JME można wyróżnić między innymi następujące " Bluetooth;
mechanizmy: " Inne:
Listing 2. Metoda nasłuchujące na TCP Listing 3. Przykładowa metoda POST
public void wait4TcpConnection() { private void doSendHTTP(String request, String url){
try { String responseStr = null;
// utworzenie serwera nasluchujacego na porcie try
3000 {
ServerSocketConnection server = //utworzenie polaczenia HTTP i ustawienie
(ServerSocketConnection) nagłowka
Connector.open("socket://:3000"); HttpConnection conn = (HttpConnection)Connector
// oczekiwanie na polaczenia .open(url);
System.out.println("Oczekiwanie na conn.setRequestMethod(HttpConnection.POST);
polaczenie..."); conn.setRequestProperty("Content-Length",
SocketConnection client = (SocketConnection) Integer.toString(reques
server.acceptAndOpen(); t.length()));
System.out.println("Zaakceptowanie polaczenia z //wyslanie wiadomosci
adresu" + client.getAddress()); OutputStream out = conn.openOutputStream();
// utworzenie strumienie wejscia/wyjscia int requestLength = request.length();
InputStream is = client.openInputStream(); for (int i = 0; i < requestLength; ++i){
OutputStream os = client.openOutputStream(); out.write(request.charAt(i));
// czytanie danych ze strumienia (dla przykladu }
do znaku konca linii \n lub gdy InputStream in = conn.openInputStream();
klient zamknal polaczenie)
int c; StringBuffer responseBuf;
StringBuffer sb = new StringBuffer(); long length = conn.getLength();
while (((c = is.read()) != -1) && (c!='\n')) { if (length > 0){
sb.append((char) c); responseBuf = new StringBuffer((int)length);
} }
else{
System.out.println("[KLIENT]" + sb.toString()); responseBuf = new StringBuffer();
//analiza wiadomosci ... }
//odczytanie odpowiedzi
//wyslanie odpowiedzi int ch;
String responseMsg = new String("Odpowiedz while ((ch = in.read()) != -1)
serwera OK\n"); {
os.write(responseMsg.getBytes()); responseBuf.append((char)ch);
}
// zamkniecie strumienii oraz polaczenia responseStr = responseBuf.toString();
is.close(); System.out.println(responseStr.toString());
os.close(); }catch (IOException e){
client.close(); e.printStackTrace();
server.close(); }catch (SecurityException e){
} catch (IOException ex) { e.printStackTrace();
ex.printStackTrace(); }
} }
}
Software Developer s Journal 6/2008 www.sdjournal.org
59
Inżynieria
oprogramowania
" JSON, konkretny obiekt typu Connection. Na Rysunku 1 przedsta-
" Burlap, wiona jest hierarchia interfejsów, które mogą implemen-
" JINI, tować obiekty zwrócone przez metodę Connector.open().
" GASP, Przezroczysty sposób tworzenia połączenia daje uniwer-
" OpenDMTP, salną metodę, która zgłasza wyjątek ConnectionNotFoun-
" Payment API, dException w przypadku gdy urządzenie nie implementuje
" Jsch. określonego połączenia.
Komunikacja TCP
niskopoziomowa oraz HTTP Transmission Control Protocol jest połączeniowym proto-
Gniazda są mechanizmem komunikacji definiującym inter- kołem zapewniającym niezawodną komunikację strumie-
fejs programowania do wymiany informacji. W Java Micro- niową. Ustanawia dwukierunkową współpracę między ho-
edition (MIDP 2.0) można zrealizować połączenia gniazd stami z możliwością sterowania przepływem (Rysunek 2).
wykorzystując UDP, TCP i TLS. Kontroluje poprawność oraz kolejność pakietów danych i
Ogólny szkielet nawiązania połączenia w JME wykony- oczekuje potwierdzania ich odbioru.
wany jest przez następującą metodę fabryki Connector.ope- W przypadku wystąpienia błędów komunikacyjnych po-
n("protocol:address;parameters") z paczki javax.microedi- trafi przeprowadzić retransmisję. Protokół TCP nie zobo-
tion.io . Metoda zwraca określony przez parametr protocol wiązuje się jednak na zrealizowanie połączenia w określo-
nym czasie.
Przy nadmiernym obciążeniu łącz daje się zaobserwo-
Listing 4. HttpServlet storna serwera http
wać nagłe spowolnienie transmisji. Spowodowane to jest
public class DeliveryServlet extends HttpServlet między innymi błędnymi pakietami i wysyłaniem żądań ich
{ ponownej retransmisji.
public void init(ServletConfig config) throws TCP w Java Microedition realizowane jest poprzez wy-
ServletException{ wołanie metody Connector.open oraz określenie minimalnie
super.init(config); parametrów: protocol jako socket oraz address jako adre-
... su hosta docelowego wraz z portem. Przykładową metodę
} wysyłającą wiadomość typu String na określony adres po-
public void doPost(HttpServletRequest request, dany w parametrach wywołania metody jest zaprezentowa-
HttpServletResponse response) ny na Listingu 1.
throws ServletException, IOException Natomiast aplikacja nasłuchująca i wykorzystująca
{ gniazda TCP jest przedstawiona na Listingu 2. Została ona
//odebranie wiadomosci od klienta i analiza jej zrealizowana w JME w celu zobrazowania możliwości tej
BufferedReader br = request.getReader(); technologii. Równie dobrze serwer oczekujący na połącze-
String buf = br.readLine(); nia może być zaimplementowany na dowolnej maszynie ob-
System.out.println(buf); sługującej gniazda TCP.
//operacje zwiazane z otrzymanymi danymi ...
//przygotowanie odpowiedzi do klienta i wysłanie jej TLS(SSL)
response.setContentType("text/html"); Transport Layer Security jest protokołem bezpieczeństwa,
PrintWriter out = response.getWriter(); który bazuje na starszym protokole Secure Socket Layer
out.println("Odpowiedz serwera OK"); (SSL).
out.close(); Ze względu na brak w TCP mechanizmów ochrony prze-
} syłanych danych wykorzystuje się TLS. Umiejscowiony jest
... on pomiędzy warstwą TCP a warstwą aplikacji co zapew-
nia prostotę jego wykorzystania w programie. Umożliwia
szyfrowanie danych, potwierdzanie tożsamości serwera/
Listing 5. Interfejs Serwera RMI
klienta, zapewnianie integralności przesyłanych komuni-
katów. W JME (MIDP 2.0) TLS realizuje się po niewielkich
package pl.awa; modyfikacjach kodu (Rysunek 3).
public interface RMIServer extends Remote {
//metoda dodaje uzytkownika
Bibliografia
public User addUser( String name, String password, Address
address)
" XML-RPC  zdalne wywoływanie procedur oparte na języku
throws RemoteException;
XML http://www.xmlrpc.com .
" WMA  Wireless Messaging API zbiór klas i metod do ob-
//zwraca obiekt klasy Address
sługi komunikacji SMS/MMS
public Address getAddress( String userName )
" http://java.sun.com/products/wma/index.jsp
throws RemoteException;
" SIP  Session Initiation Protocol protokół inicjowania sesji
" http://developers.sun.com/mobility/apis/articles/sip/
60
www.sdjournal.org
Software Developer s Journal 6/2008
Java Microedition
HTTP leceń GET lub POST. Synchronicznie tworzone są odpo-
Hypertext Transfer Protocol może służyć jako nośnik infor- wiedzi na żądanie (response).
macji między MIDletem a serwerem. Określa on formę żą- Ze względu na to że jest to protokół bezstanowy, nie
dań klienta, które tworzymy między innymi za pomocą po- zachowuje informacji o poprzednich transakcjach stosu-
je się mechanizm cookies. W przypadku Java Microedition
można wykorzystać zapis do pliku w RMS lub systemie pli-
Listing 6. Klasy implementujące interfejs Serializacji
ków (FileConnection API) urządzenia aby zapamiętać stan
import de.enough.polish.io.Serializable; transakcji. Standardowo w konfiguracji CLDC wykorzystu-
public class User implements Serializable { je się metodę Connector.open z określeniem protokołu http:
public String name; // oraz podaniem adresu serwera. Obiekt typu HttpConnec-
public Address address; tion utworzony w ten sposób posiada metodę setRequest-
public String password; Method określającą rodzaj żądania HttpConnection.POST lub
} HttpConnection.GET. W przypadku wywołania POST można
zdefiniować nagłówek http poprzez metodę setRequestPro-
import de.enough.polish.io.Externalizable; perty( name , value ) jak to jest pokazane na przykłado-
public class Address implements Externalizable { wym Listingu 3.
private String street; Właściwa treść wiadomości do serwera jest przesyła-
private String city; na strumieniowo analogicznie jak w gniazdach. Kod odpo-
public Address() { wiedzi serwera otrzymujemy za pomocą metod getRespon-
// wymagany konstruktor seCode, która zwraca statyczną wartość typu integer okre-
} ślającą kod (zdefiniowaną w klasie HttpConnection) lub ge-
public Address(String street, String city){ tResponseMessage w przypadku gdy istotna jest treść od-
super(); powiedzi.
this.street = new String(street); Natomiast stronę serwera można zrealizować w dowol-
this.city = new String(city); nej technologii obsługującej HTTP. W artykule zostanie po-
} kazana implementacja za pomocą Java Servlet. Na Listn-
public void read(DataInputStream in) throws IOException {
this.street = in.readUTF();
Listing 10. Implementacja serwera RMI
this.city = in.readUTF();
} import de.enough.polish.rmi.RemoteException;
public void write(DataOutputStream out) throws import de.enough.polish.rmi.RemoteHttpServlet;
IOException { public class GameServerImpl
out.writeUTF( this.street ); extends RemoteHttpServlet
out.writeUTF( this.city ); implements GameServer
} {
} public User addUser( String name, String password,
Address address)
throws RemoteException{
Listing 7. Poprawne wywołanie metody RemoteClient.open
//...
//utworzenie obiektu klasy User ktory bedzie zwrocony
this.server = (RMIServer) RemoteClient.open( przez metode
"pl.awa.RMIServer", User user = new User();
"http://localhost:8080/awa/myservice" ); user.name = name;
user.password = password;
user.address = address;
Listing 8. Błędne wywołanie metody RemoteClient.open
//...
return user;
String myInterfaceName = "pl.awa.RMIServer"; }
this.server = (RMIServer) RemoteClient.open( public Address getAddress( String userName ) throws
myInterfaceName, RemoteException{
"http://localhost:8080/awa/myservice" ); //...
//wyszukiwanie uzytkownika po nazwie z bazy danych
String street = getStreetFromDB(userName);
Listing 9. Zdalne wywołanie metody serwera
String city = getCityFromDB(userName);
Address address = new Address(street, city);
//... //...
User user = this.server.addUser( name, password, address); return address;
System.out.println("Name:" + user.name.toString()); }
//... }
Software Developer s Journal 6/2008 www.sdjournal.org
61
Inżynieria
oprogramowania
Connection
StreamConnectionNotifier DatagramConnection
InputConnection OutputConnection
StreamConnection
ServerSockedConnection
UDPDatagramConnection
ContentConnection (MIDP 1.0)
SockedConnection
HttpConnection (MIDP 1.0)
SecureConnection
Rysunek 1. Hierarchia interfejsów komunikacji w JME
gu 4 wykorzystany zostaje interfejs HttpServlet oraz im- Cała idea opiera się na traktowaniu obiektów zdalnych
plementacja dwóch jego metod doGET oraz doPOST, które re- w ten sam sposób jak tych działających lokalnie. W konfi-
alizują określone w nazwie żądania i generują odpowiedzi guracji CLDC JME standardowo nie można spotkać biblio-
do klienta. Aplikację serwerową można uruchomić na kon- teki odpowiedzialnej za obsługę RMI. Istnieje gotowe roz-
tenerze wspierającym serwety jak np. Apache Tomcat lub wiązanie opcjonalne J2MEPolish RMI, które jest dostęp-
JBoss. Odnośnie wykorzystania HTTPS dostępnego od ne w dwóch licencjach GPL oraz w komercyjnej Commer-
MIDP 2.0 to analogia użycia jest podobna jak w przypad- cial License.
ku TLS. Za pomocą tego narzędzia można w przyjemy i szybki
sposób zaimplementować mobilnego klienta komunikujące-
RMI go się ze zdalnym serwerem. Wszystkie wywołania metod
Remote Method Invocation jest mechanizmem, który organizuje
komunikację między obiektami Java działającymi na różnych
maszynach wirtualnych w środowisku rozproszonym. Techni-
TCP
ka ta umożliwia zdalne wywołania metod (RPC) obiektów w ję-
zyku Java w przezroczysty sposób dla programisty ukrywając
SocketConnection socketConnection =
niskopoziomowe szczegóły związane z obsługą protokołów.
(SocketConnection) Connection.open("socket://hostName:5000");
socketConnection.setSocketOption(SocketConnection.DELAY, 0);
OutputSteream os = socketConnection.openOutputStream());
Klient
Serwer
Strumień danych lub
komunikaty aplikacji
MIDIet Serwer
TLS (SSL)
Pakiety
SecureConnection socketConnection =
TCP TCP
(SecureConnection) Connector.open("ssl://hostName:5001");
String secureProtocolName =
secureConnection.getSecurityInfo().getProtocolName();
Pakiety IP
IP IP OutputSteream os = secureConnection.openOutputSteream();
Rysunek 2. Komunikacja poprzez gniazda TCP Rysunek 3. Transformacja na gniazda bezpieczeństwa TLS
62
www.sdjournal.org
Software Developer s Journal 6/2008
Framework Interfaces
CLDC Generic Connection
MIDP 2.0
Interfaces
Java Microedition
oraz dostępność obiektów dają wrażenie ich lokalnego wy- W kolejnym kroku należy zdefiniować zbiór klas, któ-
stępowania po stronie klienta i vice versa. Aby to uzmysło- re będą wspólne dla obydwu stron. Klasy te muszą imple-
wić drogiemu Czytelnikowi w dalszej części zostaną przed- mentować interfejsy serializacji de.enough.polish.io.Seria-
stawione kolejne kroki jakie należy podjąć aby to zrealizo- lizable lub de.enough.polish.io.Externalizable. Serializacja
wać. w najprostszym określeniu polega na procesie przekształ-
Na pierwszym etapie definiujemy zdalny interfejs, który bę- cenia obiektów do postaci strumienia bajtów. Dzięki zasto-
dzie wspólnym protokołem między klientem a serwerem. Okre- sowaniu tego mechanizmu w RMI można przesyłać obiek-
śla się w nim metody, które będzie udostępniał serwer. Jak ty poprzez strumieniowy protokół sieciowy. W klasie imple-
można zauważyć na Listingu 5 wymagane jest aby dziedziczył mentującej Serializable programista nie musi martwić się
on po interfejsie de.enough.polish.rmi.Remote oraz każda me- o proces serializacji dokonuje się on automatycznie jak to
toda musi mieć możliwość zgłaszania wyjątku de.enough.po- widać na Listingu 6. Natomiast różnica w klasie implemen-
lish.rmi.RemoteException. tującej Externalizable wynika z tego że należy zaimple-
Listing 11. Przykładowy plik WSDL usługi Wheather
soap="http://schemas.xmlsoap.org/wsdl/soap/" xmlns:tns="http://calculator.me.org/" xmlns:xsd="http:
//www.w3.org/2001/XMLSchema" xmlns="http://schemas.xmlsoap.org/wsdl/" targetNamespace="http://
calculator.me.org/" name="CalculatorWSService">



































Software Developer s Journal 6/2008 www.sdjournal.org
63
Inżynieria
oprogramowania
Listing 12. Klasa pnia wygenerowany automatycznie
public class CalculatorWSService_Stub implements }
CalculatorWSService, }
javax.xml.rpc.Stub {
public int add(int i, int j) throws
private String[] _propertyNames; java.rmi.RemoteException {
private Object[] _propertyValues; Object inputObject[] = new Object[] {
new Integer(i),
public CalculatorWSService_Stub() { new Integer(j)
_propertyNames = new String[] { ENDPOINT_ADDRESS_ };
PROPERTY };
_propertyValues = new Object[] { "http://localhost:8080/ Operation op = Operation.newInstance( _qname_operation_
CalculatorApp/CalculatorWSService" }; add, _type_add, _type_addResponse );
} _prepOperation( op );
op.setProperty( Operation.SOAPACTION_URI_PROPERTY,
public void _setProperty( String name, Object value ) { "" );
int size = _propertyNames.length; Object resultObj;
for (int i = 0; i < size; ++i) { try {
if( _propertyNames[i].equals( name )) { resultObj = op.invoke( inputObject );
_propertyValues[i] = value; } catch( JAXRPCException e ) {
return; Throwable cause = e.getLinkedCause();
} if( cause instanceof java.rmi.RemoteException ) {
} throw (java.rmi.RemoteException) cause;
String[] newPropNames = new String[size + 1]; }
System.arraycopy(_propertyNames, 0, newPropNames, throw e;
0, size); }
_propertyNames = newPropNames;
Object[] newPropValues = new Object[size + 1]; return ((Integer )((Object[])resultObj)[0]).intValue();
System.arraycopy(_propertyValues, 0, newPropValues, }
0, size);
_propertyValues = newPropValues; protected static final QName _qname_operation_add = new
QName( "http://calculator.me.org/",
_propertyNames[size] = name; "add" );
_propertyValues[size] = value; protected static final QName _qname_addResponse = new
} QName( "http://calculator.me.org/",
"addResponse" );
public Object _getProperty(String name) { protected static final QName _qname_add = new QName(
for (int i = 0; i < _propertyNames.length; ++i) { "http://calculator.me.org/", "add" );
if (_propertyNames[i].equals(name)) { protected static final Element _type_addResponse;
return _propertyValues[i]; protected static final Element _type_add;
} static {
} _type_addResponse = new Element( _qname_addResponse,
if (ENDPOINT_ADDRESS_PROPERTY.equals(name) || _complexType( new Element[] {
USERNAME_PROPERTY.equals(name) || new Element( new QName( "", "return" ),
PASSWORD_PROPERTY.equals(name)) { Type.INT )}), 1, 1, false );
return null; _type_add = new Element( _qname_add, _complexType(
} new Element[] {
if (SESSION_MAINTAIN_PROPERTY.equals(name)) { new Element( new QName( "", "i" ), Type.INT ),
return new Boolean(false); new Element( new QName( "", "j" ), Type.INT
} )}), 1, 1, false );
throw new JAXRPCException("Stub does not recognize }
property: " + name); private static ComplexType _complexType( Element[]
} elements ) {
ComplexType result = new ComplexType();
protected void _prepOperation(Operation op) { result.elements = elements;
for (int i = 0; i < _propertyNames.length; ++i) { return result;
op.setProperty(_propertyNames[i], _propertyValu }
es[i].toString()); }
64
www.sdjournal.org
Software Developer s Journal 6/2008
Java Microedition
poziomie kończy się definiowanie wspólnej części interfej-
su wymiany między klientem a serwerem. W dalszej części
Rejestr UDDI
należy zdefiniować klasy, które będą wykorzystywały owy
interfejs po stronie klienta i serwera. W kliencie tworzy-
my połączenie z serwerem wykorzystując metodę de.eno-
2. Wyszukiwane usługi
ugh.polish.rmi.RemoteClient.open(). Listing 7 przedstawia
poprawne konstrukcję wywołania tej metody. Przyjmuje
ona pełną nazwę interfejsu, który zdefiniowaliśmy oraz ad-
res serwera wraz ze ścieżką do serwisu RMI. Należy pa-
3. Komunikacja SOAP
1. Rejestracja usługi - opis WSDL
miętać aby definiować te parametry bezpośrednio w wy-
wołaniu metody a nie przypisując je do zmiennych a na-
stępnie przekazywaniu ich do metody jak to jest pokaza-
ne na Listingu 8.
Serwer usług
W przypadku sukcesu nawiązania połączenia z serwe-
rem poprzez powyższą metodę klient może wywoływać me-
tody serwera poprzez interfejs o nazwie (RMIServer). Wy-
Rysunek 4. Web services podstawowe elementy i operacje korzystuje się do tego referencje obiektu, który zwróciła
metoda open jak to przedstawia Listing 9.
mentować metody read i write, które odpowiednio czyta- W odpowiedzi w tym przypadku zwracany jest obiekt
ją ze strumienia oraz zapisują do strumienia. Jeśli jednak klasy z którym należy obchodzić się zupełnie w sposób
nie ma potrzeby tworzenia nowych klas, które będą nośni- lokalny.
kiem informacji możemy wykorzystać standardowe klasy Ostatnim etapem konstruowania naszego mechanizmu
Java Microedition takie jak np. String lub Vector. W zależ- wykorzystującego RMI jest implementacja serwera. Klasa
ności o skomplikowania zastosowania mogą one stanowić serwera jest serwletem dziedziczącym po de.enough.po-
elementy parametrów metod jak i być zwracane przez me- lish.rmi.RemoteHttpServlet oraz implementująca jednocze-
tody serwera. Większość standardowych klas wspiera se- śnie metody naszego wspólnego interfejsu o nazwie RMI-
rializację jednak występują pewne ograniczenia w niektó- Server (Listing 10). Jest to część wykonawcza całego me-
rych przypadkach. chanizmu i należy zadbać o poprawną konstrukcję zwra-
Zalecane jest zapoznanie się przed ich zastosowaniem canych obiektów.
w dokumentacji dostępnej na stronie J2MEPolish. Na tym Proces kompilacji oraz budowania serwera wykra-
cza poza ramy tego artykułu, która prezentuje tylko za-
rys z poziomu języka Java. Jednak dla ułatwienia w kata-
Listing 13. Zdalny interfejs serwera
logu {j2mepolish-dir}/samples/rmi znajduje się przykłado-
public interface CalculatorWSService extends java.rmi.Remote
{
W Sieci
public int add(int i, int j) throws java.rmi.RemoteExc
eption;
" http://developers.sun.com/mobility/allarticles/#networking
" h t t p : // d e ve l o p e r s . s u n . c o m / m o b i l i t y / m i d p / a r t i c l e s/
}
socketRMI/
" http://www.j2mepolish.org/cms/leftsection/documentation/
rmirpc.html
Listing 14. Przykład wywołania metody serwera
" http://kxmlrpc.objectweb.org
" http://ksoap.objectweb.org/
public Integer getRemoteResult(int x, int y){ " ht tp : //w w w.netbeans .org /kb / 60 /mobilit y /mobile - dil-
bert.html
Integer result = null;
" http://developers.sun.com/mobility/allarticles/#ws
try{
" http://developers.sun.com/mobility/allarticles/#wma
" http://ksync.objectweb.org
//utworzenie obiektu reprezentujacego serwer
" http://developers.sun.com/mobility/midp/articles/syncml/
CalculatorWSService webClient = new
" ht tp ://java.sun.com /developer/ Books /J2MEwireless/
CalculatorWSService_Stub();
J2ME12.pdf
//wywolanie zdalnej metody
" http://developers.sun.com/mobility/midp/articles/jxme/
int z = webClient.add(x, y);
" http://developers.sun.com/mobility/allarticles/#wma
" http://tavon.org/work/JSON-J2ME
result = new Integer(z);
" http://www.forum.nokia.com/main/resources/technologies/
}catch (Exception ex) { java/documentation/networking.html
" http://developer.sonyericsson.com/wiki/display/leftnav/
System.err.print(ex);
Java+Connectivity
}
" http://developer.motorola.com/docstools/
return result;
" http://developer.samsungmobile.com/Developer/index.jsp
}
Software Developer s Journal 6/2008 www.sdjournal.org
65
Inżynieria
oprogramowania
larnego HTTP(S). W porównaniu do JSE wersja mobilna
jest poddana znacznym restrykcjom:
" nie wspiera asynchronicznych wiadomości;
" brak załączników w SOAP;
" wiadomości w reprezentacji literal (document/literal);
" brak wsparcia mapowania typów (brak paczki ja-
vax.xml.rpc.encoding);
" brak mechanizmu wyszukiwania UDDI.
Napisanie MIDletu zintegrowanego z serwerem za pomo-
cą SOAP dokonujemy od zlokalizowania adresu url usłu-
gi Web Service.
W artykule dla ułatwienia zostanie wykorzystany przy-
kładowy serwis Calculator pochodzący z pakietu NetBe-
Rysunek 5. Carbide.j oraz NeatBeans IDE 6.0 generowanie
pnia ans 6.0 (menu File->New Project->Samples->Web Service-
>Calculator).
wy projekt gdzie został napisany skrypt w ANT budujący Zostaje on uruchomiony na lokalnym serwerze także do-
jednocześnie aplikację klienta i serwer. Będzie on stano- łączonym do tego narzędzia. Zatem adres do pliku wsdl jest
wił pomocą deskę dla początkujących programistów. Uwa- następujący: http://localhost:8080/CalculatorApp/CalculatorW
gę należy zwrócić na proces obfuskacji dokonywany czę- SService?wsdl
sto podczas budowania aplikacji. Podczas tego procesu Definicja pliku WSDL dla danego serwisu może wyglądać
paczka jar wspólnych klas także zostaje poddana tej opty- tak jak to przedstawia Listing 11.
malizacji. W dalszej kolejności przechodzimy do realizacji klienta w
Należy pamiętać, że jeśli dokonano obfuskacji to pacz- którym należy zaimplementować:
ka jar wspólnych klas musi się znalezć po obu stronach
jednocześnie na kliencie jak i na serwerze. Pominięcie te- " stub czyli pień czyli najprościej określając klasę przez
go faktu jest sygnalizowane najczęściej wyjątkiem Class którą przechodzą wszystkie żądania i odpowiedzi z
not found: a lub Class cast exception wynika to przede serwera;
wszystkim ze zmiany nazwy klas po zakończeniu pracy " interfejs serwisu;
obfuscatora. " klasę uruchamiającą zdalną metodę Web Service.
Web Services SOAP Generowanie klasy pnia można dokonać automatycznie korzy-
Simple Object Access Protocol jest standardem wymiany stając z takich narzędzi jak Carbide.j lub Netbeans IDE 6.0,
informacji, którego składnia oparta jest na XML. Protokół WTK Sun 2.5. We wszystkich przypadkach po prostu należy
SOAP należy do grupy rozwiązań określanych terminem podać adres url do pliku WSDL Web Service jak jest to poka-
Web Services. zane na Rysunku 5 .
Technologia Web Services zapewnia konstrukcję roz- Więcej informacji na temat tych narzędzi oraz wspo-
proszonych komponentów usługowych. W ramach Web mnianego procesu znajduje się na stronach: http://www.j
Services oprócz SOAP odpowiedzialnego za zdalne wy- 2mepolish.org/cms/leftsection/documentation/rmirpc.html, http://
woływanie usługi, istnieje jeszcze WSDL oraz UDDI (Ry- kxmlrpc.objectweb.org. W wyniku zautomatyzowanego działa-
sunek 4). nia tych narzędzi zostaje wygenerowana klasa pnia (Listing 12)
Język opisu interfejsu WSDL (Web Services Descrip- oraz zdalny interfejs serwera (Listing 13).
tion Language) służy do dystrybucji usług sieciowych nie- Utworzone w ten sposób klasy po prostu dołączamy do
zależnie od jej implementacji. UDDI (Universal Descrip- naszej aplikacji. Przykładowe wywołanie metody serwera
tion, Discovery and Integration) ułatwia udostępnianie do- przy zastosowaniu wygenerowanych klas przedstawia Li-
kumentów WSDL przez umieszczenie ich w specjalnej ba- sting 14.
zie danych. Jak można zaobserwować proces tworzenia klienta oka-
Zarejestrowane komponenty usług mogą być następnie zał się w większości automatyczny. Cała technika tworzenia
przeszukiwane przez klientów w celu ich wykorzystania. jest przezroczysta dla programisty. Wygenerowane klasy są
Wracając do Java Microedition komunikację SOAP moż- bezpośrednio napisane w Java ukrywając szczegóły imple-
na zrealizować wykorzystując z jednej strony opcjonalną mentacyjne SOAP.
paczkę JSR-172 lub dołączyć do aplikacji bibliotekę jar z
implementacją tego protokołu. Specyfikacja JSR-172 Web Podsumowanie
Service jest uboższym zbiorem interfejsów pochodzącym Aby ułatwić Czytelnikowi wybór właściwej metody do swoje-
od JSE API JAX-RPC(1.1). Dostarcza infrastrukturę Web go zastosowania zostanie przedstawione krótkie zestawienie
Services bazująca na synchronicznym modelu zdalnych mocnych i słabych stron opisanych metod.
wywołań procedur RPC. Gniazda są szybkim rozwiązaniem w przypadku pro-
Oferuje szeroką paletę typów danych oraz komunikację stych wiadomości nie wymagające definiowania rozbudo-
poprzez wiele protokołów sieciowych między innymi popu- wanego protokołu. Dostępne są na każdym urządzeniu od
66
www.sdjournal.org
Software Developer s Journal 6/2008


Wyszukiwarka

Podobne podstrony:
2006 06 Wstęp do Scrum [Inzynieria Oprogramowania]
2008 06 the Way of the Ray Enterprise Collaboration with Liferay
2008 06 Living Free Free Communications on the Freenet Network
2008 06 Czy boisz się Slackware [Poczatkujacy]
Metodyka Integrowanej Ochrony MALINY PRODUCENT
06 Java dziedziczenie 0
Metodyka integrowanej ochrony pieczarki
2008 06 teleinformatyk arkusz x
2008 06 Virtual machines [Consumer test]
Magia interfejsu Praktyczne metody projektowania aplikacji internetowych magint
Metodyka Integrowanej Ochrony TRUSKAWKI PRODUCENT
Metodyka Integrowanej Ochrony PORZECZKI
2007 06 UML – potrzeba standaryzacji notacji [Inzynieria Oprogramowania]
Metodyka Integrowanej Ochrony PORZECZKI PRODUCENT

więcej podobnych podstron