Модераторы: javastic, AntonSaburov

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Реализация сетевого соединения http? 
:(
    Опции темы
Kalisnik
Дата 3.3.2012, 18:08 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 61
Регистрация: 21.6.2011

Репутация: нет
Всего: нет



Добрался до сетевого соединения. Был бы благодарен за правильный рабочий пример передачи и приема данных по протоколу http с подробными комментариями, что бы по ним можно было понять суть и механизм процесса. Спасибо!
PM MAIL   Вверх
oxigen
Дата 5.3.2012, 11:47 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 142
Регистрация: 12.4.2010

Репутация: 4
Всего: 4



Читаем по http картинку и показываем ее
Код

  protected void startApp() throws MIDletStateChangeException {
            HttpConnection conn = null;
            DataInputStream is = null;
                try {
                    conn = (HttpConnection) Connector.open("http://av.li.ru/227/2374227_8677578.jpg", Connector.READ, false); //создали connection.
                                                                        // Connector.open - умный. Создаст тип в зависимости от преффикса адреса. Здесь HTTP
                    conn.setRequestMethod( HttpConnection.GET);  // Используем Get запрос

                    int rc = conn.getResponseCode();                       //!!! Именно здесь происходит отсылка запроса и получение ответа

                    if (rc != HttpConnection.HTTP_OK) {                   // Если от сервера пришел код ответа != 200, то значит что-то пошло не так. 
                        throw new Exception("ResponseCode = " + rc);   // Нужно конечно как-то более разумно обработать ошибку.
                    }

                    is = conn.openDataInputStream();                    //ответ получен. И находится в connection. Достаем его 
                    byte []b = new byte[(int) conn.getLength()];    //в виде массив байт
                    is.readFully(b);

                    Image img = Image.createImage(b, 0, b.length);    // Все. Делаем с получеными байтами что хотим. Здесь хотим картинку.
                    Form f = new Form("test");                                      // Был бы к примеру текст - читали бы в строку. [I]new String(b)[/I]
                    f.append(img);
                    Display.getDisplay(this).setCurrent(f);

                } catch (Exception e) {

                } finally {
                   if(conn != null)
                         conn.close();
                    if(is != null)
                         is.close();
                }

    }


Нужно учесть, что обмен данными через сеть - процесс небыстрый. И пока он будет происходить - приложение "заморозится" и не будет ни на что реагировать. Ни на какие действия пользователя.
Чтоб этого избежать, подобные вещи принято делать в отдельном потоке.


Это сообщение отредактировал(а) oxigen - 5.3.2012, 15:01
PM MAIL   Вверх
Kalisnik
Дата 6.3.2012, 22:47 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 61
Регистрация: 21.6.2011

Репутация: нет
Всего: нет



1. HttpConnection - это интерфейс или класс? В api написанно что интерфейс, а используется он как класс. Не поняно. Разве переменная(данные) может иметь тип интерфейса?

2. В чем различия InputStream и DataInputStream? В каких случаях использовать тот или этот?

3. Касательно Connector.open, что меняет второй параметр Connector.READ? Соединение только для чтения? Ставил Connector.WRITE - ни чего не изменилось. Почему не ставить сразу универсально Connector.READ_WRITE? Что делает 3-й параметр? Что-то с таймаутом связанное вроде - выбрасывать ли исключение по таймауту?

Это сообщение отредактировал(а) Kalisnik - 6.3.2012, 23:31
PM MAIL   Вверх
oxigen
Дата 7.3.2012, 11:51 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 142
Регистрация: 12.4.2010

Репутация: 4
Всего: 4



1. HttpConnection - это интерфейс или класс? В api написанно что интерфейс, а используется он как класс. Не поняно. Разве переменная(данные) может иметь тип интерфейса?
Конечно может иметь тип интерфейса. Интерфейсы для того и придуманы
Код

class A extends Cl1 implements I1, I2, I3 {}

//Использование
A a = new A();
Cl1 с = new A();
I1 i1 = new A();
I2 i2 = new A();

Все это корректно и все эти переменные физически будут ссылаться на объект класса A
Разница в том, что для a мы сможем вызавать все методы, а для i1 только те, которые описаны в интерфейсе I1. Но это все равно будут одни и те же методы.

conn = (HttpConnection) Connector.open(...);
Эта строка означает, что Connector возвращает какой-то объект. Нам совершенно не нужно знать, какого он конкретно класса. Все что мы про него знаем - в нем есть методы, описаные в интерфейсе HttpConnection. Этого достаточно.


2. В чем различия InputStream и DataInputStream? В каких случаях использовать тот или этот?
Использовал DataInputStream ради его метода readFully. Проще.
Можно использовать и InputStream во всяком случае в документации именно для него пример.
http://docs.oracle.com/javame/config/cldc/...r118/index.html

3. Касательно Connector.open
Действительно для Http соединения достаточно было только одного параметра. Издержки бездумного копипаста :(
Connector.open("http://av.li.ru/227/2374227_8677578.jpg");
Третий параметр задает поведение при таймауте соединения. Если true - будет выброшен Exception

PM MAIL   Вверх
Kalisnik
Дата 7.3.2012, 12:05 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 61
Регистрация: 21.6.2011

Репутация: нет
Всего: нет



oxigen, по поводу интерфейсов. Видимо я не доканца понимаю что это такое. Можете объяснить своими словами, с основными приемами их использования?

З.Ы. Код выше для меня оказался совершенно новым. Такого еще не видел.

Это сообщение отредактировал(а) Kalisnik - 7.3.2012, 12:52
PM MAIL   Вверх
oxigen
Дата 7.3.2012, 15:43 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 142
Регистрация: 12.4.2010

Репутация: 4
Всего: 4



Интерфейсы - это множественное наследование в java

Зачем нужно множественное наследование?
Вот в вашем предыдущем примере был слушатель нажатий на меню
Код

public class Stra extends Form implements CommandListener {
...
setCommandListener(this);
...
public void commandAction(Command c, Displayable d) {}
}

Как все это работает? Вы листенером делали и мидлет и форму и просто Object. И оно  работало.
Как сделать подобное?

Внутри класса Displayable должен быть примерно такой код
Код

private CommandListener listener

public void setCommandListener(CommandListener l) {
    listener = l
}

//если нажали на пункт меню, то выполняется
  listener.commandAction(command, this);


То есть слушателем у нас может кто угодно. Абсолютно любой класс. Нашему Displayable безразлично, кто именно его слушает.
Единственное, что он требует, чтоб у слушателя был метод commandAction(Command c, Displayable d)
И для этого требования и сделан интерфейс CommandListener. 
В нем описан только один метод commandAction(Command c, Displayable d)

Метод setCommandListener(CommandListener l) принимает любой класс, который implements CommandListener.
А раз он implements CommandListener, то значит ему можно сообщить о нажатии на меню через  listener.commandAction(command, this);

Не знаю, может сумбурно написал. Если непонятно, то конкретная задача - как изменить ваш Stra, чтоб любой класс мог узнавать о том, какая кнопка была нажата. Для ее решения понадобится создать интерфейс и добавить код как выше.
PM MAIL   Вверх
Kalisnik
Дата 10.3.2012, 17:49 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 61
Регистрация: 21.6.2011

Репутация: нет
Всего: нет



1. Да. Оказывается понимал я все правильно. Только практического опыта не хватает и момент с переменными типа-интерфейс я как-то упустил, от чего и возникло недоумение. По сути интерфейс это некий "протокол", правила взаимосвязи самостоятельных звеньев системы. Если какой-либо класс использует интерфейс, то это означает что он "кровью" подписывается реализовать все методы этого интерфеса и выполнять их по первому требованию в любое время дня и ночи. smile Скажем, речь на которой общаются все участники сего форума также является интерфейсом (тип: "Русский язык"): слова - абстрактные методы, а их смысловое содержание - конкретная реализация в каждом индивиде. smile) Касательно переменных типа интерфейс. Как Вы и говорили, они просто ссылаются на методы какого-либо класса, который использует интерфейс такого же типа. По сути, тип этих переменных есть не "интерфейс", а "Класс", который использует этот интефейс, но с фильтром методов. Вроде так получается. )
    Далее Вы говорите о множественном наследовании - видимо как о практической ценности интерфейсов. "Не знаю, может сумбурно написал. Если непонятно, то конкретная задача - как изменить ваш Stra, чтоб любой класс мог узнавать о том, какая кнопка была нажата. Для ее решения понадобится создать интерфейс и добавить код как выше." - вообще-то я действительно недопонял. )) Может рабочий примерчик, что бы я мог его откомпилировать, запустить и посмотреть как все работает?

2. И еще в догонку вопросик. http работает по принципу "отправил запрос - получил ответ". А если клиентскому приложению нужно отслеживать изменения на сервере? Значит нужно систематично отправлять запросы и проверять изменения. А если клиентов 1000 или 10 000 и все разом отправят запрос? Так и сервер положить недолго. )) Значит либо делать сложные костыли вроде распределенных во времени запросов всей сети клиентов, либо... искать альтернативы http. Есть ли эти самые альтернативы? Т.е. можно ли сделать так, что бы приложение слушало сервер без запроса и как только сервер отсылает конкретному клиенту данные, клиент соответсвенно их обрабатывает?

Это сообщение отредактировал(а) Kalisnik - 10.3.2012, 21:50
PM MAIL   Вверх
oxigen
Дата 12.3.2012, 11:52 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 142
Регистрация: 12.4.2010

Репутация: 4
Всего: 4



1. Собственно у слова интерфейс есть два значения. 
Первое - интерфейс класса. Это все публичные методы класса. Через которые другие классы могут к нему обращаться.
Второе  - интерфейс, который ключевое слово interface. Это способ описать некоторое подмножество первого.

Если говорить о языке, то скажем Вы можете общаться голосом и письменно.

class Kalisnik implemens Voiceable, Writable
И у вас есть public методы для обработки письменных и устных слов. Это Ваш интерфейс, через который окружающие могут обратиться к вам.

Однако для форума Вы
Writable kalisnik;
То есть я могу обращаться к Вам только через методы, которые описаны в interface Writable (письменная речь)

Каой-то небольшой пример, где будет видна необходимость интерфейсов, не так легко сочинить.
Почитайте лучше какую-то хорошую книгу именно по Java (не по мобильной). Философия JAVA Брюса Эккеля к примеру. Он понятнее, чем я объясняет нюансы наследования и необходимость интерфейсов.

2. HTTP действительно работает так, что одна сторона посылает запросы, а вторая - отсылает на них ответы.
Если надо, чтоб процесс был симметричным, то больше подходит соединение через сокет
conn = (SocketConnection) Connector.open("socket://your_url:port"); 
Пример в доке http://docs.oracle.com/javame/config/cldc/...r118/index.html
Устанавливаете соединение через сокет и все.
И тогда Вы просто кладете то, что нужно отправить на сервер в OutputStream, А то, что сервер отправил - появляется в InputStream.



Это сообщение отредактировал(а) oxigen - 12.3.2012, 12:04
PM MAIL   Вверх
Kalisnik
Дата 12.3.2012, 15:44 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 61
Регистрация: 21.6.2011

Репутация: нет
Всего: нет



oxigen, спасибо smile Просто я не понял Ваш конкретный пример с CommandListener - про него говорил. Не понял как Вы хотели изменить Stra. А так в общем-то все доступно и понятно. )

Это сообщение отредактировал(а) Kalisnik - 12.3.2012, 15:48
PM MAIL   Вверх
oxigen
Дата 12.3.2012, 17:44 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 142
Регистрация: 12.4.2010

Репутация: 4
Всего: 4



Я имел ввиду что-то вроде
Код

public class Stra extends Form implements CommandListener{
    private Vector listeners = new Vector();

    public void addListener(StraListener listener) {
       listeners.addElement(listener);
   }

    public void commandAction(Command c, Displayable d) {
         for(int i = 0; i < listener.size(); i++) {
                ((StraListener)listeners.elementAt(i)).straAction(geTitle(), c.getLabel());
        }

        if(c == ok){
            Midlet.midl.getDisplay().setCurrent(getFormByIndex(choice.getSelectedIndex(), d));
        }else if(c == back){
            back();
        }else if(c == exit){
            Midlet.midl.destroyApp(true);
        }
        
    }
    
}

interface StraListener {
   public straAction(String title, String Action);
}


И теперь если понадобится прикрутить любой класс, который должен как-то реагировать на переключения форм, не надо будет каждый раз менять Stra.
Захотели - прикрутили класс, пишущий в консоль.

Код

public class Logger implements StraListener {
    Logger() {
     stra1.addListener(this);
     stra2.addListener(this);
    }

    public straAction(String title, String action) {
        System.out.println(title + "menu item pressed " + action);
    }

}

Захотели - аналогично прикрутили класс, отсылающий на сервер данные про изменения или еще что.
Главная фишка - что для добавления этой новой функциональности уже не требуется каждый раз менять класс Stra.

Как-то так. Просто пример слегка надуманый.

Это сообщение отредактировал(а) oxigen - 13.3.2012, 16:46
PM MAIL   Вверх
Kalisnik
Дата 12.3.2012, 18:43 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 61
Регистрация: 21.6.2011

Репутация: нет
Всего: нет



oxigen,  вот теперь понял. )) Да, после первого примера с переменными типа-интерфейс, я уже осознал перспективы использования этого типа (т.е. интерфейсов) в параметрах метода. Мощная штука!

З.Ы. Ошибочку увидел... на случай если кому-то тоже будет интересен этот пример:

Код

for(int i = 0; i < listeners.size(); i++) {
                ((StraListener)listeners[i]).straAction(geTitle(), c.getLabel());
        }


Это сообщение отредактировал(а) Kalisnik - 12.3.2012, 18:57
PM MAIL   Вверх
oxigen
Дата 13.3.2012, 11:04 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 142
Регистрация: 12.4.2010

Репутация: 4
Всего: 4



Исправил. Но только  ((StraListener)listeners.elementAt(i)) Там же вектор а не массив.
PM MAIL   Вверх
Kalisnik
Дата 13.3.2012, 15:27 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 61
Регистрация: 21.6.2011

Репутация: нет
Всего: нет



Ясно. Здесь (http://www.javaportal.ru/java/class/Vector.html) сбили с толку. Вектором пока еще не пользовался. Получается это та же коллекция, с автоматическим расширением памяти? Вообще много заметил в интернете умельцев, которые пишут статьи и сами не знают про что пишут. По ссылке выше Vector - это массив. Другие пишут что HttpConnection - это класс, хотя на самом деле это интерфейс... видимо надо учить английский и читать официальную документацию. Правильных переводов официальной документации ведь нет?

з.ы.  "s" - забыли )

Это сообщение отредактировал(а) Kalisnik - 13.3.2012, 15:30
PM MAIL   Вверх
oxigen
Дата 13.3.2012, 17:06 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 142
Регистрация: 12.4.2010

Репутация: 4
Всего: 4



Внутри вектора действительно спрятан массив. Но благодаря инкапсуляции нам это неважно.

Насчет коллекций учитывайте одну вещь. Спецификация J2ME очень старая. И в J2ME нет интерфейса Collection.
После появления в JAVA этого интерфейса, Vector и Hashtable были сильно изменены, стали наследниками Collection и в них соответствующие методы. 
http://www.javaportal.ru/java/class/Vector.html - описание этого нового вектора.

Но в векторе из J2ME этих новых методов нет.
http://docs.oracle.com/javame/config/cldc/...r118/index.html - J2ME вектор 


Фанатские переводы документации периодически пытаются делать. Может найдете что-то.


Это сообщение отредактировал(а) oxigen - 13.3.2012, 17:21
PM MAIL   Вверх
Kalisnik
Дата 22.3.2012, 19:55 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 61
Регистрация: 21.6.2011

Репутация: нет
Всего: нет



Цитата(oxigen @  12.3.2012,  11:52 Найти цитируемый пост)
Устанавливаете соединение через сокет и все.И тогда Вы просто кладете то, что нужно отправить на сервер в OutputStream, А то, что сервер отправил - появляется в InputStream.


Это мне, получается, в телефонном приложении два сокета создавать надо? Один клиентский, другой серверный - что будет слушать "во вне"? Тогда как интересно сервер (что "во вне") будет отсылать телефону запросы, если ip-адрес телефона заранее не известен? Получается, приложение телефона должно сделать запрос на сервер, где определится его ip, и тогда сервер сможет подключиться к ServerSocketConnection телефона? Так?

Это сообщение отредактировал(а) Kalisnik - 22.3.2012, 19:57
PM MAIL   Вверх
Ответ в темуСоздание новой темы Создание опроса

  • Прежде чем задать вопрос прочтите это!
  • Литература по Java находится здесь.
  • Литературу по Java обсуждаем здесь.
  • Используйте теги [code=java][/code] для подсветки кода. Используйтe чекбокс "транслит" (возле кнопок кодов) если у Вас нет русских шрифтов.
  • Действия модераторов можно обсудить здесь
  • С просьбами о написании курсовой, реферата и т.п. обращаться сюда

  • FAQ раздела лежит здесь!
 
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | Java ME (J2ME) | Следующая тема »


 




[ Время генерации скрипта: 0.0532 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.