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