2003 EST JAVA PROJESİ Barış EFE İTÜ Bilişim Enstitüsü, Maslak, İstanbul İtü Bilişim Enstitiüsü Sayfa 1 / 27 İÇERİK 1 ÖZET ................................................................................................................................ 3 2 TERİMLER ..................................................................................................................... 3 3 GİRİŞ .............................................................................................................................. 3 4 TEKNOLOJİ – NEDİR BU J2ME? ....................................................................... 4 4.1 KONFİGÜRASYON VE PROFİLLER................................................................... 5 4.1.1 CLDC Konfigürasyonu ................................................................................ 6 4.1.2 CDC Konfigürasyonu................................................................................... 7 4.1.3 MIDP Profili ..................................................................................................... 7 4.1.4 CDC Tabanlı Bazı Profiller ......................................................................... 9 4.2 MIDP PROGRAMMING, MIDLETLER ............................................................... 9 4.2.1 MIDlet Yaşam Döngüsü ............................................................................. 9 4.2.2 MIDP Kullanıcı Arabirimi .......................................................................... 10 4.2.3 MIDlet Suites ve Uygulama Tanımlayıcıları ..................................... 11 4.2.4 MIDlet Örneği .............................................................................................. 12 5 USE-CASE DIAGRAMI .......................................................................................... 13 6 VERİTABANI YAPISI ............................................................................................ 13 7 MIDLETLER ................................................................................................................ 15 7.1 7.2 7.3 7.4 7.5 STUDENT.JAVA: ....................................................................................................... 15 STUDENTNUMBERSCREEN.JAVA: ........................................................................... 17 INFOSCREEN.JAVA: ................................................................................................. 18 WAİTCANVAS.JAVA: ............................................................................................... 20 HTTPWORKER.JAVA: ............................................................................................... 21 8 SERVLET ...................................................................................................................... 24 9 SONUÇLAR ................................................................................................................. 27 10 KAYNAKLAR .......................................................................................................... 27 İtü Bilişim Enstitiüsü Sayfa 2 / 27 1 ÖZET Bu projenin amacı J2ME(Java 2, Micro Edition) MIDP profili ve Java Servlet teknolojileri kullanarak öğrencilerin J2ME MIDP profilini destekleyen kablosuz cihazlarından sunucuya bağlanarak çeşitli bilgileri sorgulamalarını sağlayan bir sistem geliştirmektir. 2 TERİMLER J2ME : Java 2 Micro Edition küçük cihazlar için tanımlanmış bir grup belirtim ve teknolojidir. J2ME belli sınıflardaki cihazlar için bir grup konfigürasyon ve profillere bölünmüştür. CLDC: CLDC(Connected, Limited Device Configuration) J2ME nın en yaygın konfigürasyonudur. CLDC 512 KB tan ufak hafızası ve sınırlı ağ bağlantısı olan aletler için tasarlanmıştır. CLDC KVM olarak adlandırılan JVM(Java Virtual Machine) i ve uygulamalar için temel olan bir takım kütüphaneleri belirler. MIDP : Mobile Information Device Profile J2ME nin bir profilidir. CLDC nin üstündeki bir profil olarak yer alır ve uygulamanın yaşam döngüsü, kullanıcı grafik arabirimleri, iletişim ağı ve kalıcı depolama ile ilgili kütüphaneleri içerir. Midlet : MIDLET MIDP profili için yazılmış uygulamalara verilen isimdir. MIDlet suite: MIDletler MIDlet Suite ler olarak paketlenir ve dağıtılır. Bir Midlet Suite bir veya daha fazla Midlet ten oluşabilir. Midlet Suite .jar ve.jad olarak 2 dosyadan meydana gelir. .jad uzantılı dosya tanımlayıcı dosya, .jar uzantılı dosya Midlet, kullanılan kütüphaneler, kaynak dosyaları gibi dosyaları içeren arşiv dosyasıdır. Servlet : Java nın sunucu tarafında çalışan bir teknolojisidir. 3 GİRİŞ Projenin bir ayağında bir MIDlet uygulaması geliştirilecek ve bu uygulama kablosuz cihaza yüklendikten sonra sunucu üzerinde bulunan Servlet ile iletişime geçerek yapılan sorgulamalara göre kullanıcıya bilgi sunacaktır. İlk olarak öğrenciler, midlet olarak geliştirilmiş uygulamayı Bilişim Enstitüsünün sanaldoku yöresinden kablosuz cihazlarına yüklerler. Daha sonra bu uygulama üzerinden yapılan sorgulamalar ile servletle iletişime geçilir ve gerekli bilgiler kablosuz cihazlarında gösterime sunulur. İtü Bilişim Enstitiüsü Sayfa 3 / 27 4 TEKNOLOJİ – NEDİR BU J2ME? Java ilk olarak avuçiçi ve taşınabilir cihazlar için tasarlanmış fakat sonraları çeşitli sebeplerden dolayı çıkış amacından uzaklaşmıştır. Java, J2ME ile çıkış günlerindeki amacına geri dönmektedir. Günümüzde Java platformu 3 ana kategoriye ayrılır: 1. Standard Edition (J2SE): Daha çok kişisel bilgisayarlara yönelik bir takım standartları içerir. Java 2 SDK (J2SE) Java 2 Runtime Environment Java Plug-in Java Web Start Java HotSpot Server Virtual Machine Collections Framework Java Foundation Classes (JFC) Swing Components Pluggable Look & Feel Accessibility Drag and Drop Security Java IDL JDBC JavaBeans Remote Method Invocation (RMI) Java 2D 2. Enterprise Edition (J2EE): Sunuculara yönelik geliştirilen bir takım standartları içerir. Enterprise JavaBeans (EJB) Architecture JavaServer Pages (JSP) Java Servlet Java Naming and Directory Interface (JNDI) Java IDL JDBC Java Message Service (JMS) Java Transaction (JTA) Java Transaction Service (JTS) JavaMail RMI-IIOP Software Development Kit & Application Model Java 2 SDK, Enterprise Edition (J2EE) Sun BluePrints Design Guidelines for J2EE 3. Micro Edition (J2ME): Cep telefonları, kablosuz el cihazları, kişisel dijital asistanlar ve benzeri kaynakları kısıtlı cihazlar için geliştirilen standartları içerir. Java 2 Platform, Micro Edition (J2ME technology) Connected Device Configuration (CDC) Connected Limited Device Configuration (CLDC) C Virtual Machine (CVM) K Virtual Machine (KVM) PersonalJava İtü Bilişim Enstitiüsü Sayfa 4 / 27 JavaPhone API Java TV API Jini Network Technology Mobile Information Device Profile (MIDP) J2ME sadece bir bir belirtim değildir. J2ME, kablosuz cihaz pazarının farklı bölümleri için geliştirilmiş belirtim ve teknolojilerin toplamıdır. Kablosuz cihaz pazarının çeşitliliğinden dolayı herşeye uyacak standart bir çözüm getirilemediğinden dolayı böyle bir çözüm üretilmiştir. JAVA Kavram Haritası: 4.1 KONFİGÜRASYON VE PROFİLLER J2ME çeşitli konfigürasyon ve profillere bölünmüştür. Konfigürasyonlar JVM(Java Virtual Machine) detaylarını ve belli sınıftaki İtü Bilişim Enstitiüsü Sayfa 5 / 27 cihazlarla kullanılabilecek temel kütüphaneleri tanımlayan belirtimlerdir. Mesela 512KB bellekten az hafıza alanı ve sınırlı bir ağ bağlantısı olan cihazların konfigürasyonu CLDC olarak adlandırılır. CLDC lere örnek olarak bazı cep telefonları ve avuç içi bilgisayarlar(PDAs) verilebilir. Daha fazla belleğe ve işlemci gücüne sahip, sürekli ağ bağlantısı olan diğer konfigürasyon ise CDC olarak adlandırılır (Connected Device Configuration). Bunlara örnek olarak ise Sharp Zaurus avuç içi bilgisayarları verilebilir. Profiller uygulama geliştirmeye daha yetkin bir ortam sunabilmek için konfigürasyonun üzerine tanımlanan kütüphanelerdir. Konfigürasyon java sanal makinesi (JVM) ve temel kütüphaneleri tanımlarken, bir uygulama geliştirilirken ihtiyaç duyulabilecek yetkinlikte kütüphaneleri tanımlamaz. Profiller bu alanda uygulamanın yaşam döngüsü, kullanıcı arabirimi ve kalıcı bellek kütüphanelerini içerirler. J2ME Konfigürasyon ve Profil Haritası: Şimdi bu konfigürasyon ve profillerden bazılarını inceleyelim: 4.1.1 CLDC Konfigürasyonu CLCD(Connected, Limited Device Configuration) daha kısıtlı kaynaklara sahip cihazlara yönelik bir J2ME konfigürasyonudur. Bu profilin çekirdeğinde bir java sanal makinesi olan KVM yatmaktadır. KVM, JVM in bazı kısımlarının çıkartılarak daha önemli ve gerekli parçalarını içerecek şekilde tasarlanmış halidir. KVM ismindeki K harfi bu sanal makinenin Megabyte boyutunda hafızayla değil Kilobyte boyutunda hafıza ile çalışabilmesinden gelmektedir. Bu konfigürasyon 512 KB tan ufak hafızası ve sınırlı ağ bağlantısı olan cihazlar için tasarlanmıştır. İtü Bilişim Enstitiüsü Sayfa 6 / 27 Bu konfigürasyonun ait Java paketleri: java.io java.lang java.lang.ref java.util javax.microedition.io 4.1.2 CDC Konfigürasyonu CLCD(Connected Device Configuration) daha az kısıtlı kaynaklara sahip cihazlara yönelik bir J2ME konfigürasyonudur. Bu profilin çekirdeğinde de CVM(Compact Virtual Machine) sanal makinesi bulunmaktadır. Genellikle CLDC den daha fazla hafıza ve işlemci gücüne sahip cihazlarda kullanılır. Ayrıca bu cihazlar sürekli ağ bağlantısına sahiptirler. Bu konfigürasyonun ait Java paketleri: java.io java.lang java.lang.ref java.lang.reflect java.math, java.net java.security java.security.cert java.text, java.util java.util.jar, java.util.zip javax.microedition.io 4.1.3 MIDP Profili MIDP(Mobile Information Device Profile) mevcut profiller arasında ilk ve en yaygın olanıdır ve uygulamanın yaşam döngüsü, kullanıcı grafik arabirimleri, iletişim ağı ve kalıcı depolama ile ilgili kütüphanelerini içerir. MIDP CLDC konfigürasyonunun üzerine oturur ve günümüzde Motorola, Nokia, Ericsson ve RIM(Blackburry) gibi sector devleri tarafından desteklenmektedir. MIDP 1.0 ın desteklediği paketler: java.io java.lang,java.util javax.microedition.io javax.microedition.lcdui javax.microedition.midlet javax.microedition.rms İtü Bilişim Enstitiüsü Sayfa 7 / 27 MIDP 2.0 ın desteklediği paketler: java.io java.lang java.util javax.microedition.io javax.microedition.lcdui javax.microedition.lcdui.game javax.microedition.media javax.microedition.media.control javax.microedition.midlet, javax.microedition.pki javax.microedition.rms Günümüzde J2ME özelliğine sahip cep telefonlarının büyük bir çoğunluğu aşağıdaki özellikleri içermektedir: MIDP kapasiteli cihaz mimarisi: İtü Bilişim Enstitiüsü Sayfa 8 / 27 4.1.4 CDC Tabanlı Bazı Profiller CDC konfigürasyonu üzerindeki bazı profiller şunlardır: Foundation Profil, Personal Basis Profil ve Personal Profil. Basit olarak tanımlamak gerekirse Foundation Profil CDC nin üzerine ektradan J2SE nesneleri ekler. Bu profile sahip cihazların en onemli özelliği sürekli ağ bağlantısı olmasına karşılık kullanıcı arabirimine sahip olmamasıdır. Ayrıca ekstra güvenlik nesneleri kullanır. Daha çok diğer profillere temel oluşturur. Personal Profil Foundation Profil üzerinde AWT kullanıcı arabirimi nesnelerinin bir alt kümesini içerir. Personal Profil ise PersonalJava uygulama çevresini J2ME profile olarak yeniden tanımlar. Bu profil AWT kullanıcı arabirimi nesnelerini daha fazla kapsayacak şekilde tanımlanmıştır. CDC tabanlı bazı profiler ve ilişkileri: 4.2 MIDP PROGRAMMING, MIDLETLER MIDP profili için yazılan uygulamalar Midlet olarak tanımlanır. Bir MIDP uygulaması geliştirmek için bazı temel bilgileri edinmek gerekir. Bunlardan bazıları: midletlerin yaşam döngüsü, kullanıcı arabirimleri, komut işleme, konuşlandırma ve uygulama yönetimi olarak sayılabilir. 4.2.1 MIDlet Yaşam Döngüsü Uygulama Yönetim Yazılımı(Application Management Software, AMS) midlet in kurulumu, başlaması, durdurulması ve kaldırılması ile ilgili işlemlerin yapıldığı ortamdır. AMS Java Uygulama Yöneticisi (Java Application Manager) olarak da bilinir. İtü Bilişim Enstitiüsü Sayfa 9 / 27 Midletler 3 durumda bulunabilir: durağan (paused), etkin (active), ölü(destroy). Bir midlet yaratıldığı ve başlatıldığı zaman durağan moddadır. Eğer MIDlet yapılandırıcısında(constructor) kural dışı bir durum oluşursa(exception) MIDlet ölü durumuna geçer. MIDlet ler etkin durumdan durağan durumuna pauseApp() methodunu tamamladıktan sonra geçebilirler. Veya etkin konumdan durağan duruma startApp() methodunu tamamladıktan sonra geçebilirler. MIDletler ölü konumuna destroyApp(boolean unconditional) methodunun tamamlanmasından sonra geçerler.Bu method MIDlet kullandığı kaynakları serbest bırakır ve gerekli temizleme işlemlerini yapar. Bir MIDlet yazılımcısı yazılımını etkin modda çalıştırır ve gerektiği zaman diğer durumlar arasında geçişleri sağlar. 4.2.2 MIDP Kullanıcı Arabirimi MIDP kullanıcı arabirimi düşük ve ve yüksek düzey olmak üzere iki ana kategoriye ayrılır. Düşük düzey kullanıcı arabirimi Canvas isimli nesneye dayanır. Yüksek düzey kullanıcı arabirim nesneleri ise Alert, Form, List ve TextBox olarak sıralanabilir. Bu nesnelerin görünüş biçimleri profilin gerçekleştirildiği cihazların kullanıcı arabirimlerine göre değişebilir. Canvas nesnesi ile kullanıcı arabirimine daha direk kontrol sağlanır. Mesela ekranda nelerin çizileceği ve klavye olayları hakkında daha geniş bir kontrol sağlanır. Kullanıcı arabirimlerini kullanırken en önemli, dikkat edilmesi gereken nokta yazacağımız MIDletlerin değişik kapasiteli cihazlarda çalışabiliyor olmasıdır. Dolayısı ile ekran genişliği, ekranın renkli İtü Bilişim Enstitiüsü Sayfa 10 / 27 veya siyaz-beyaz oluşuna göre bir takım kontroller yaptırarak MIDletlerimizi bu değişik ortamlara uyum sağlayabilecek şekilde yazmalıyız. 4.2.3 MIDlet Suites ve Uygulama Tanımlayıcıları Uygulama Yönetim Yazılımı(Application Management Software, AMS) midlet in kurulumu, başlaması, durdurulması ve kaldırılması ile ilgili işlemlerin yapıldığı ortamdır. Bir veya daha fazla MIDlet ‘MIDlet Suite’ denen JAR uzantılı dosyalara paketlenir. Her JAR dosyasının içeriğini tanımlayan JAD uzantılı uygulama tanımlayıcı dosyası vardır. Bu dosyalar Uygulama Yönetim Yazılımları tarafından kullanılır. JAR ve JAD uzantılı dosyaların cep telefonlarına indirilebilmesi için bu dosyaların indirileceği web sunucuları üzerinde aşağıdaki MIME tiplerinin tanımlanması gerekmektedir: .jar application/java-archive .jad text/vnd.sun.j2me.app-descriptor Ayrıca uygulama tanımlayıcısından dinamik olarak değer almak için MIDlet içinden getAppPropoerty (String key) methodu da kullanılabilir. Böylece JAR dosyasını değiştirmeye gerek kalmadan JAD dosyası üzerinden bazı değişiklikler ile MIDlet imizin çeşitli işlevlerini değiştirebiliriz. Örnek bir JAD dosyası: İtü Bilişim Enstitiüsü Sayfa 11 / 27 MIDlet-1: MerhabaDunya, , example.hello.HelloWorldMIDlet MIDlet-2: ZiplayanYazi, , example.hello.BouncingTextMIDlet MIDlet-Jar-Size: 7822 MIDlet-Jar-URL: HelloExamples.jar MIDlet-Name: HelloExamples MIDlet-Vendor: Ozgur Yazilim MIDlet-Version: 1.0.1 ZiplayanYazi-BaslangicYazisi: MIDlet ler eğlenceli! Yukarıdaki MIDlet Suite, Uygulama Yönetim Yazılımı tarafından yüklendiğinde hangi MIDlet in başlatılmak istendiği sorulacak, seçime gore ilgili MIDlet sisteme yüklenerek çalıştırılacaktır. 4.2.4 MIDlet Örneği import javax.microedition.midlet.*; import javax.microedition.lcdui.*; public class MerhabaDunya extends MIDlet implements CommandListener { // çıkış komutu private Command exitCommand; // display nesnesi private Display display; // ticker yarat private Ticker hi = new Ticker("J2ME ornegi"); public MerhabaDunya() { display = Display.getDisplay(this); exitCommand = new Command("Cikis", Command.SCREEN, 2); } 0); public void startApp() { TextBox t = new TextBox("Merhaba Dunya", "Ilk yazim", 256, t.addCommand(exitCommand); t.setCommandListener(this); t.setTicker(hi); display.setCurrent(t); } public void pauseApp() { } İtü Bilişim Enstitiüsü Sayfa 12 / 27 public void destroyApp(boolean unconditional) { } public void commandAction(Command c, Displayable s) { if (c == exitCommand) { destroyApp(false); notifyDestroyed(); } } } 5 USE-CASE DIAGRAMI 6 VERİTABANI YAPISI CREATE TABLE student ( student_id int(5) NOT NULL auto_increment, student_number int(5) NOT NULL default '0', student_firstname varchar(32) NOT NULL default '', student_lastname varchar(32) NOT NULL default '', student_department_id int(5) NOT NULL default '0', PRIMARY KEY (student_id) ) TYPE=MyISAM; INSERT INTO student VALUES (1, 111, 'Baris', 'Efe', 1); INSERT INTO student VALUES (2, 222, 'Ali', 'Aksel', 1); CREATE TABLE student_announcement ( student_announcement_id int(5) NOT NULL auto_increment, student_announcement_text varchar(255) NOT NULL default '', PRIMARY KEY (student_announcement_id) ) TYPE=MyISAM; İtü Bilişim Enstitiüsü Sayfa 13 / 27 INSERT INTO student_announcement VALUES (1, 'Finaller Ocak ayinin 2 haftasina ertelendi.'); INSERT INTO student_announcement VALUES (2, 'Ogrenci kimlikleri dagitilmaya baslandi.'); CREATE TABLE student_course ( student_course_id int(5) NOT NULL auto_increment, student_course_name varchar(255) NOT NULL default '', PRIMARY KEY (student_course_id) ) TYPE=MyISAM; INSERT INTO student_course VALUES (1, 'Java'); INSERT INTO student_course VALUES (2, 'SQL'); INSERT INTO student_course VALUES (3, 'C'); CREATE TABLE student_department ( student_department_id int(5) NOT NULL auto_increment, student_department_name varchar(100) NOT NULL default '', PRIMARY KEY (student_department_id) ) TYPE=MyISAM; INSERT INTO student_department VALUES (1, 'EST'); CREATE TABLE student_news ( student_news_id int(5) NOT NULL auto_increment, student_news_text varchar(255) NOT NULL default '', PRIMARY KEY (student_news_id) ) TYPE=MyISAM; INSERT INTO student_news VALUES (1, 'Rektorun konusmasi 3 Ocak 2003 14:00 te Fen Fakultesinde'); INSERT INTO student_news VALUES (2, 'Kutuphaneye yeni Java kitaplari alindi.'); INSERT INTO student_news VALUES (3, 'Maslak kampusunde yeni kantin aciliyor.'); CREATE TABLE student_score ( student_score_id int(5) NOT NULL auto_increment, student_number int(5) NOT NULL default '0', student_course int(5) NOT NULL default '0', student_score varchar(255) NOT NULL default '', PRIMARY KEY (student_score_id) ) TYPE=MyISAM; INSERT INTO student_score VALUES (1, 111, 1, '67'); INSERT INTO student_score VALUES (2, 111, 2, '87'); INSERT INTO student_score VALUES (3, 111, 3, '34'); INSERT INTO student_score VALUES (4, 222, 2, '97'); INSERT INTO student_score VALUES (5, 222, 3, '48'); İtü Bilişim Enstitiüsü Sayfa 14 / 27 7 MIDLETLER MIDletler bir ana nesne, duruma göre değişen ekranlar için tasarlanmış nesneler ve ağ bağlantısını sağlayan nesneden meydana geliyor. MIDletlerin kaynak kodları: 7.1 Student.java: /** * Student.java * @author Baris Efe * @version 1.0 */ package studentlet; import import import import java.io.*; javax.microedition.io.*; javax.microedition.lcdui.*; javax.microedition.midlet.*; public class Student extends MIDlet implements CommandListener { private static Student instance; private InfoScreen scrInfoScreen; private StudentNumberScreen scrStudentNumberScreen; private WaitCanvas scrWait; private Command cancelCommand ; private HttpWorker httpWorker; public String studentNumber; private static String url = "http://localhost:8080/student"; /** Constructor */ public Student() { instance = this; } /** Main method */ public void startApp() { Displayable current=Display.getDisplay(this).getCurrent(); if (current==null){ scrInfoScreen = new InfoScreen(this); scrStudentNumberScreen = new StudentNumberScreen(this); Display.getDisplay(this).setCurrent(scrStudentNumberScreen); scrWait = new WaitCanvas(); İtü Bilişim Enstitiüsü Sayfa 15 / 27 cancelCommand = new Command("Iptal", Command.CANCEL, 0); scrWait.addCommand(cancelCommand); scrWait.setCommandListener(this); httpWorker = new HttpWorker(this, scrWait, url); httpWorker.start(); } else { Display.getDisplay(this).setCurrent(current); } } /** Handle pausing the MIDlet */ public void pauseApp() { } /** Handle destroying the MIDlet */ public void destroyApp(boolean unconditional) { } /** Quit the MIDlet */ public static void quitApp() { instance.destroyApp(true); instance.notifyDestroyed(); instance = null; } public void networkResponse(String s) { //System.out.println("debug, Student.networkResponse(), "+s); if(s.compareTo("false")==0) { scrStudentNumberScreen.setResultText("Ogrenci numarasi bulunamadi. Lutfen tekrar deneyiniz."); this.studentNumber=""; Display.getDisplay(this).setCurrent(scrStudentNumberScreen); } else { scrInfoScreen.setResultText(s); Display.getDisplay(this).setCurrent(scrInfoScreen); } } public void runHttpWorker(String queryString) { httpWorker.setQueryString(queryString); httpWorker.go(); } public void showWaitScreen() { scrWait.setMessage("Baglaniyor..."); İtü Bilişim Enstitiüsü Sayfa 16 / 27 Display.getDisplay(this).setCurrent(scrWait); } public void showStudentNumberScreen() { Display.getDisplay(this).setCurrent(scrStudentNumberScreen); } public void commandAction(Command c, Displayable s) { if (c == cancelCommand) { Display.getDisplay(this).setCurrent(scrInfoScreen); httpWorker.cancel(); } } } 7.2 StudentNumberScreen.java: /** * StudentNumberScreen.java * @author Baris Efe * @version 1.0 */ package studentlet; import import import import java.io.*; javax.microedition.io.*; javax.microedition.lcdui.*; javax.microedition.midlet.*; public class StudentNumberScreen extends Form implements CommandListener{ private Student midlet; private StringItem txtResultText; private TextField txtStudentNumber; public StudentNumberScreen(Student midlet) { super("Ogrenci Bilgi"); this.midlet=midlet; try { txtStudentNumber = new TextField("Ogrenci Numarasi:","",10,0); txtResultText = new StringItem("", ""); setCommandListener(this); İtü Bilişim Enstitiüsü Sayfa 17 / 27 addCommand(new Command("Gonder", Command.OK, 1)); this.append(txtStudentNumber); this.append(txtResultText); } catch(Exception e) { e.printStackTrace(); } } public void setResultText(String httpResponseText) { txtResultText.setText(httpResponseText); } public void commandAction(Command command, Displayable displayable) { if (command.getCommandType() == Command.OK) { midlet.studentNumber = txtStudentNumber.getString(); midlet.showWaitScreen(); midlet.runHttpWorker("action=getStudentNumber&studentNumber="+txt StudentNumber.getString()); } } } 7.3 InfoScreen.java: /** * InfoScreen.java * @author Baris Efe * @version 1.0 */ package studentlet; import import import import java.io.*; javax.microedition.io.*; javax.microedition.lcdui.*; javax.microedition.midlet.*; public class InfoScreen extends Form implements CommandListener{ private Student midlet; private StringItem txtResultText; İtü Bilişim Enstitiüsü Sayfa 18 / 27 public InfoScreen(Student midlet) { super("Ogrenci Bilgi"); this.midlet=midlet; try { txtResultText = new StringItem("", ""); setCommandListener(this); addCommand(new Command("Duyuru?", Command.SCREEN, 1)); addCommand(new Command("Haber?", Command.SCREEN, 1)); addCommand(new Command("Not?", Command.SCREEN, 1)); addCommand(new Command("Numara?", Command.SCREEN, 1)); addCommand(new Command("Cikis", Command.SCREEN, 1)); this.append(txtResultText); } } catch(Exception e) { e.printStackTrace(); } public void setResultText(String httpResponseText) { txtResultText.setText(httpResponseText); } public void commandAction(Command command, Displayable displayable) { if (command.getCommandType() == Command.OK) { midlet.showWaitScreen(); midlet.runHttpWorker("action=test"); } else if (command.getCommandType() == Command.SCREEN) { String commandName = command.getLabel(); System.out.println("commandName:"+commandName); if (commandName.equals("Duyuru?")) { midlet.showWaitScreen(); midlet.runHttpWorker("action=announcement"); } else if (commandName.equals("Haber?")) { midlet.showWaitScreen(); midlet.runHttpWorker("action=news"); } else if (commandName.equals("Not?")) { midlet.showWaitScreen(); midlet.runHttpWorker("action=scores&studentNumber="+midlet.studentN umber); } else if (commandName.equals("Numara?")) { midlet.showStudentNumberScreen(); } else if (commandName.equals("Cikis")) { midlet.quitApp(); İtü Bilişim Enstitiüsü Sayfa 19 / 27 } } } } 7.4 WaitCanvas.java: /** * WaitCanvas.java * @author Baris Efe * @version 1.0 */ package studentlet; import import import import java.util.*; java.io.*; javax.microedition.io.*; javax.microedition.lcdui.*; public class WaitCanvas extends Canvas { private int mCount, mMaximum; private int mInterval; private int mWidth, mHeight, mX, mY, mRadius; private String mMessage="Studentlet..."; public WaitCanvas() { mCount = 0; mMaximum = 36; mInterval = 100; mWidth = getWidth(); mHeight = getHeight(); // Calculate the radius. int halfWidth = (mWidth - mRadius) / 2; int halfHeight = (mHeight - mRadius) / 2; mRadius = Math.min(halfWidth, halfHeight); // Calculate the location. mX = halfWidth - mRadius / 2; mY = halfHeight - mRadius / 2; İtü Bilişim Enstitiüsü Sayfa 20 / 27 // Create a Timer to update the display. TimerTask task = new TimerTask() { public void run() { mCount = (mCount + 1) % mMaximum; repaint(); } }; Timer timer = new Timer(); timer.schedule(task, 0, mInterval); } public void setMessage(String s) { mMessage = s; repaint(); } public void paint(Graphics g) { int theta = -(mCount * 360 / mMaximum); // Clear the whole screen. g.setColor(255, 255, 255); g.fillRect(0, 0, mWidth, mHeight); // Now draw the pinwheel. g.setColor(0, 0, 0); g.drawArc(mX, mY, mRadius, mRadius, 0, 360); g.fillArc(mX, mY, mRadius, mRadius, theta + 90, 90); g.fillArc(mX, mY, mRadius, mRadius, theta + 270, 90); } // Draw the message, if there is a message. if (mMessage != null) g.drawString(mMessage, mWidth / 2, mHeight, Graphics.BOTTOM | Graphics.HCENTER); } 7.5 HttpWorker.java: /** * HttpWorker.java * @author Baris Efe * @version 1.0 */ package studentlet; İtü Bilişim Enstitiüsü Sayfa 21 / 27 import java.io.*; import javax.microedition.io.*; import javax.microedition.lcdui.*; public class HttpWorker extends Thread { private Student midlet; private WaitCanvas scrWait; private String url; private HttpConnection httpConnection; private boolean mTrucking, mCancel; private String queryString = null; public HttpWorker(Student midlet, WaitCanvas waitCanvas, String url) { this.midlet=midlet; scrWait = waitCanvas; this.url = url; mTrucking = true; mCancel = false; } public synchronized void run() { while (mTrucking) { try { wait(); } catch (InterruptedException ie) {} if (mTrucking) connect(); } } public synchronized void setQueryString(String queryString) { this.queryString=queryString; } public synchronized void go() { notify(); } public void cancel() { try { mCancel = true; if (httpConnection != null) httpConnection.close(); } catch (IOException ignored) {} } İtü Bilişim Enstitiüsü Sayfa 22 / 27 public synchronized void stop() { mTrucking = false; notify(); } private void connect() { InputStream is = null; OutputStream os = null; try { byte postmsg[] = queryString.getBytes(); System.out.println("debug: HttpWorker.connect(), queryString:"+queryString); // Query the server and retrieve the response. scrWait.setMessage("Gonderiyor..."); httpConnection = (HttpConnection)Connector.open(url); httpConnection.setRequestMethod(HttpConnection.POST); httpConnection.setRequestProperty("User-Agent", "Profile/MIDP1.0 Configuration/CLDC-1.0"); httpConnection.setRequestProperty("Content-Language", "enUS"); httpConnection.setRequestProperty("Content-Type", "application/x-www-form-urlencoded"); os = httpConnection.openOutputStream(); for(int i=0; i < postmsg.length;i++) { os.write(postmsg[i]); } is = httpConnection.openInputStream(); // Pull back the server's response. If a content length is not // specified, we'll just read 255 bytes. int contentLength = (int)httpConnection.getLength(); if (contentLength == -1) contentLength = 255; byte[] raw = new byte[contentLength]; int length = is.read(raw); // Clean up. is.close(); httpConnection.close(); // Show the response to the user. String s = new String(raw, 0, length); midlet.networkResponse(s); İtü Bilişim Enstitiüsü Sayfa 23 / 27 } catch (IOException ioe) { if (mCancel == false) { try { if (is != null) is.close(); if (httpConnection != null) httpConnection.close(); } catch (IOException ignored) {} } mCancel = false; } } } 8 SERVLET MIDlet servlet ile iletişime geçerek gerekli bilgileri MySQL üzerinden okur ve MIDlet’e gerekli bilgileri geri döner. Kaynak kodu aşağıda verilmiştir: student.java: package studentserver; /** * @author Baris Efe * @version 1.0 */ import import import import import javax.servlet.*; javax.servlet.http.*; java.io.*; java.util.*; java.sql.*; public class student extends HttpServlet { static final private String CONTENT_TYPE = "text/html"; static Connection Conn = null; static ResultSet rs = null; static Statement Stmt = null; static String DBUrl = "jdbc:mysql:///student"; // MySQL Connection address //Initialize global variables İtü Bilişim Enstitiüsü Sayfa 24 / 27 public void init() throws ServletException { } //Process the HTTP Get request public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { doPost(request, response); } //Process the HTTP Post request public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { try { int i; response.setContentType(CONTENT_TYPE); PrintWriter out = response.getWriter(); String action = (String)request.getParameter("action"); // MySQL Connection Class.forName("com.mysql.jdbc.Driver").newInstance(); Conn = DriverManager.getConnection(DBUrl); Stmt = Conn.createStatement(); if (action!=null) { if (action!="") { //System.out.println("debug, action:"+action); if (action.compareTo("news")==0) { rs = Stmt.executeQuery("SELECT student_news_text FROM student_news"); i=0; while (rs.next()) { i++; out.println(i+". Haber: "+rs.getString("student_news_text")); } rs.close(); } else if (action.compareTo("announcement")==0) { rs = Stmt.executeQuery("SELECT student_announcement_text FROM student_announcement"); i=0; while (rs.next()) { i++; out.println("Duyuru "+i+": "+rs.getString("student_announcement_text")); } rs.close(); } else if (action.compareTo("scores")==0) { İtü Bilişim Enstitiüsü Sayfa 25 / 27 String studentNumber = (String)request.getParameter("studentNumber"); rs = Stmt.executeQuery("SELECT student_course_name, student_score FROM student_score, student_course WHERE student_number="+studentNumber+" AND student_course.student_course_id=student_score.student_course "); while (rs.next()) { out.println(rs.getString("student_course_name")+": "+rs.getString("student_score")+"."); } rs.close(); } else if (action.compareTo("getStudentNumber")==0) { boolean isStudentNumberInteger; String studentNumber = (String)request.getParameter("studentNumber"); try { Integer.parseInt(studentNumber); isStudentNumberInteger = true; } catch(NumberFormatException e) { isStudentNumberInteger = false; } if (isStudentNumberInteger) { rs = Stmt.executeQuery("SELECT * FROM student WHERE student_number="+studentNumber); if (rs.next()) { out.println("Hosgeldin "+rs.getString("student_firstname")+" "+rs.getString("student_lastname")+"."); } else { out.print("false"); } rs.close(); } else { out.print("false"); } } } else { out.println("Gecersiz istek."); } } } catch (Exception E) { System.out.println(E.toString()); } İtü Bilişim Enstitiüsü Sayfa 26 / 27 } //Clean up resources public void destroy() { } } 9 SONUÇLAR Bu proje ile J2ME Java teknolojisi detayları ile incelenmiş ve ağ üzerinden servlet ile konuşarak öğrenci bilgilerini sorgulayan bir MIDlet gerçekleştirilmiştir. Servlet istenen bilgiler doğrultusunda MySQL üzerinden sorgulamaları gerçekleştirerek MIDlete gönderir. Kullanıcının, ağ üzerinden sorgulama esnasında cevapsız bırakılmaması için ağ bağlantısı multithread olarak gerçekleştirilir. Bu proje ile J2ME teknolojisi kullanılarak bir uygulama gerçekleştirilmiş ve bunun çeşitli yönleri gerçekleştirilmiştir. 10 KAYNAKLAR 1. 2. 3. 4. 5. 6. Sun Microsystems, http://wireless.java.sun.com/. Nokia, http://www.forum.nokia.com. CoreJ2ME, http://www.corej2me.com/. Micro Java Network, http://www.microjava.com/. Nakane_Kasumi, O'Reilly, J2ME in a Nutshell. O'Reilly OnJava, http://www.onjava.com/onjava/wireless/ İtü Bilişim Enstitiüsü Sayfa 27 / 27