Interval.cz
J2ME v kostce û jak se p°ipojit k serveru

I kdy₧ lokßlnφ javovΘ aplikace v²razn∞ rozÜi°ujφ mo₧nosti mobilnφho telefonu, mnohem zajφmav∞jÜφ mohou b²t aplikace s p°ipojenφm k serveru, a¥ u₧ pro p°φstup k aktußlnφm firemnφm dat∙m, komunikaci se znßm²mi pomocφ ICQ klienta nebo "mobilnφ" sprßvu serveru s pou₧itφm ssh klienta. Jak se z telefonu dostat na sφ¥ se nauΦφte v tomto Φlßnku.

Sφ¥ovΘ mo₧nosti J2ME

Rovnou vßm prozradφm, ₧e zatφm nejsou p°φliÜ velkΘ. V²robci telefon∙ jsou povinni implementovat pouze HTTP spojenφ. Navφc jsou jeÜt∞ rozdφly v tom, kolik spojenφ m∙₧e b²t otev°eno zßrove≥, nejlΘpe je poΦφtat rovnou pouze s jednφm (Nokia), nepφÜete-li aplikaci specißln∞ pro jedno konkrΘtnφ za°φzenφ, kterΘ vφce soub∞₧n²ch p°ipojenφ podporuje.

┌dajn²m d∙vodem, proΦ je vy₧adovßno pouze HTTP spojenφ, je to, ₧e n∞kterΘ mobilnφ sφt∞ jsou implementovßny zp∙sobem, kter² by se t∞₧ko p°izp∙soboval p°ipojenφ p°es sokety, kde₧to u HTTP spojenφ je celkem jedno, jakΘ jsou ni₧Üφ vrstvy sφt∞. Z vlastnφ zkuÜenosti mohu °φct, ₧e n∞kterΘ telefony sokety podporujφ (nap°. od firmy Siemens Φi Motorola) a minimßln∞ u T-mobile fungujφ.

Ve specifikaci MIDP-2.0 jsou sice oproti souΦasnΘmu MIDP-1.0 p°idßna navφc n∞kterß nφzko·rov≥ovß rozhranφ, nap°φklad na ji₧ zmi≥ovanΘ sokety Φi dokonce UDP datagram, ale telefony tyto typy p°ipojenφ nemusφ podporovat. Ani novß specifikace nßm pak p°φliÜ nepom∙₧e a aplikace psanΘ obecn∞ pro vÜechny telefony si budou muset vystaΦit s HTTP protokolem, kter² mß pon∞kud nepraktickou vlastnost, ₧e vyluΦuje iniciaci spojenφ ze serveru.

HttpConnection

T°φdy a rozhranφ pot°ebnΘ pro sφ¥ovΘ p°ipojenφ obsahuje balφk javax.microedition.io. Ne₧ p°ejdu ke konkrΘtnφmu p°φkladu, je pot°eba si jeÜt∞ n∞co °φci o nejd∙le₧it∞jÜφm rozhranφ, kterΘ budeme pou₧φvat, a to HttpConnection.

HTTP protokol mß formu po₧adavek-odpov∞∩ a vÜechny parametry musφ b²t nastaveny d°φve, ne₧ je po₧adavek odeslßn. Od toho se odvφjφ stavy, ve kter²ch se HTTP spojenφ m∙₧e nachßzet:

  • Nastavenφ (Setup) û spojenφ jeÜt∞ nenφ navßzßno
  • P°ipojeno (Connected) û parametry byly odeslßny, Φekß se na odpov∞∩
  • Zav°eno (Closed) û p°i volßnφ metod je vyhozena IOException

Nßsledujφcφ metody mohou b²t volßny pouze ve fßzi nastavenφ:

  • setRequestMethod
  • setRequestProperty

Do p°ipojenΘho stavu p°ejde HTTP spojenφ zavolßnφm n∞kterΘ z metod, kterΘ vy₧adujφ komunikaci se serverem:

  • openInputStream
  • openOutputStream
  • openDataInputStream
  • openDataOutputStream
  • getLength
  • getType
  • getEncoding
  • getHeaderField
  • getResponseCode
  • getResponseMessage
  • getHeaderFieldInt
  • getHeaderFieldDate
  • getExpiration
  • getDate
  • getLastModified
  • getHeaderField
  • getHeaderFieldKey

P°φklad

DneÜnφ p°φklad neobsahuje ₧ßdnou zßbavnou pointu, prost∞ se jen p°ipojφ k URL, kterΘ naΦte z atributu v JAD souboru, a ve formulß°i zobrazφ jeho obsah. Sklßdß se ze dvou t°φd: TestHttpMIDlet coby zßkladnφ t°φdy midletu a TestHttp pro naΦtenφ URL.

P°ipojenφ k serveru

import java.io.IOException;
import java.io.InputStream;

import javax.microedition.io.Connector;
import javax.microedition.io.HttpConnection;
/**
 * Tato t°φda slou₧φ pro komunikaci se serverem pomocφ
 * HTTP spojenφ.
 */

public class TestHttp {

    /**
     * Metoda connect naΦte danΘ URL a vrßtφ jako String.
     * @param url URL kterΘ se mß naΦφst
     * @return String Obsah danΘho URL
     * @throws IOException - Nem∙₧e-li b²t spojenφ vytvo°eno nebo
     * nastane-li jinß I/O chyba
     */

    public static String connect(String url)
        throws IOException {
        HttpConnection c = null;
        InputStream is = null;

        try {

            // Vytvo°enφ HTTP p°ipojenφ
            c = (HttpConnection) Connector.open(url);

            // Nastavenφ p°φstupovΘ metody
            c.setRequestMethod(HttpConnection.GET);

            // Otev°enφ vstupnφho proudu - po zavolßnφ tΘto metody
            // se HttpConnection nachßzφ v p°ipojenΘm stavu
            is = c.openInputStream();

            String s = null;

            // ZjiÜt∞nφ dΘlky p°ijat²ch dat
            int len = (int) c.getLength();
            if (len > 0) {
                // DΘlka dat je p°edem znßmß
                byte[] data = new byte[len];
                int actual = is.read(data);
                s = new String(data);
            } else {
                // DΘlka dat nenφ p°edem znßmß
                StringBuffer buf = new StringBuffer();
                int ch;
                while ((ch = is.read()) != -1) {
                    buf.append((char) ch);
                }
                s = buf.toString();

            }
            return s;

        // I kdy₧ nastane n∞jakß v²jimka, je pot°eba zav°φt
        // InputStream a HttpConnection, proto se tyto p°φkazy
        // dajφ do finally bloku, kter² se provede v₧dy.
        } finally {
            if (is != null) {
                is.close();
            }
            if (c != null) {
                c.close();
            }
        }
    }
}

Midlet

Komunikace se serverem je Φasov∞ velmi nßroΦnß zßle₧itost, aby proto neblokovala u₧ivatelskΘ prost°edφ, je pot°eba ji provΘst v jinΘm ne₧ hlavnφm vlßkn∞.

import javax.microedition.lcdui.*;
import javax.microedition.midlet.*;

/**
 * Jednoduch² midlet, kter² naΦte z JAD souboru parametr url,
 * pak se na danΘ URL p°ipojφ a naΦtenß data zobrazφ na displeji
 */

public class TestHttpMIDlet
   extends MIDlet
   implements CommandListener, Runnable {

   private Form loading;
   private Form form;
   private Command exit;
   private Display display;
   private String url;

   /**
    * Konstruktor t°φdy - vytvo°φ formulß°
    */

   public TestHttpMIDlet() {
      form = new Form("TestHttp");
      exit = new Command("Konec", Command.BACK, 1);
      form.addCommand(exit);
      form.setCommandListener(this);
      loading = new Form("");
      loading.append("Nahrßvßm...");
      loading.setTicker(new Ticker("Pracuju"));
      url = getAppProperty("url");
   }

   /**
    * Tuto metodu volß aplikaΦnφ mana₧er p°i p°echodu midletu
    * do aktivnφho stavu.
    */

   protected void startApp()
      throws MIDletStateChangeException {
      if (display == null) {
         display = Display.getDisplay(this);
      }
      display.setCurrent(loading);
      Thread t = new Thread(this);
      // SpuÜt∞nφ druhΘho vlßkna, ve kterΘm probφhß
      // p°ipojenφ k serveru
      t.start();
   }

   /**
    * Tuto metodu volß aplikaΦnφ mana₧er p°i p°echodu midletu
    * do pasivnφho stavu
    */
   protected void pauseApp() {
      // Jeliko₧ odkaz na druhΘ vlßkno nenφ globßlnφ,
      // nenφ zde pot°eba nic d∞lat
   }

   /**
    * Tuto metodu volß aplikaΦnφ mana₧er p°i ukonΦenφ aplikace
    */

   protected void destroyApp(boolean unconditional)
      throws MIDletStateChangeException {
   }

   /**
    * Metoda rozhranφ CommandListener
    */

   public void commandAction(Command c, Displayable d) {
      if (c.equals(exit)) {
         try {
            destroyApp(true);
            notifyDestroyed();
         } catch (Exception e) {
         }
      }
   }

   /**
    * Metoda rozhranφ Runnable na naΦtenφ URL a zobrazenφ
    * ve formulß°i - provßdφ ji druhΘ vlßkno
    */

   public void run() {
      String s;
      try {
         s = TestHttp.connect(url);
      } catch (Exception e) {
         s = e.getMessage();
      }
      form.append(s);
      display.setCurrent(form);
   }
}

Literatura a odkazy

P°edchozφ Φlßnky



Lucie Rut Bittnerovß (19.12. 2002)
programßtor û analytik Amaio Technologies

Redakce Interval.cz |  Inzerce na Interval.cz |  Hledßme novΘ autory ISSN 1212-8651 
 ⌐ Zoner software, s.r.o., vÜechna prßva vyhrazena, tento server dodr₧uje prßvnφ p°edpisy o ochran∞ osobnφch ·daj∙.