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

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> URLConnection: java.net.ProtocolException, Возникает после попытки записи в поток 
:(
    Опции темы
T_Serg
Дата 5.8.2009, 15:29 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



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

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



Перед созданием POST запроса к серверу необходимо прочитать контент странички. Это необходимо для того, чтобы узнать поле name тегов, которые нужно послать с пост запросом (при каждом обращении к страничке генерируется новое значение поля name необходимого тега)
Я пытаюсь cделать так:
Код

            url = new URL("http://www.aaa.bb");

            URLConnection urlConnection = url.openConnection();
            urlConnection.setDoInput(true);
            urlConnection.setDoOutput(true);
            InputStream input=urlConnection.getInputStream();
            //тут обрабатывается страничка и получается поля name необходимых тегов
            input.close();

                //далее забиваем их как параметры Post запроса
                        PrintWriter output = new PrintWriter(urlConnection.getOutputStream());
            output.print("tag1");
            output.print('=');
            output.print(URLEncoder.encode("value1", "UTF-8"));
            output.print("tag2");
            output.print('=');
            output.print(URLEncoder.encode("value2", "UTF-8"));
            output.close();
            
                        //считываю ответ  сервера после Post запроса
            Scanner scanner=new Scanner(urlConnection.getInputStream());
                       //......


В результате получаю 
java.net.ProtocolException: Cannot write output after reading input.
    at sun.net.www.protocol.http.HttpURLConnection.getOutputStream(Unknown Source)

Возможно ли в одном соединении URLConnection делать и get и post запросы?
PM MAIL   Вверх
COVD
Дата 5.8.2009, 18:13 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1655
Регистрация: 26.7.2005

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



нет
PM MAIL   Вверх
T_Serg
Дата 6.8.2009, 09:23 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



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

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



а другими способами это возможно реализовать? например апачевским HTTPClient?
PM MAIL   Вверх
COVD
Дата 6.8.2009, 12:53 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1655
Регистрация: 26.7.2005

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



URLConnection по возможности использует одно физическое соединение при повторных обращениях к одному хосту (если не применять disconnect() после каждого запроса), хотя обьект URLConnection надо каждый раз создавать новый. Это, наверное, вводит в заблуждение.  Применять HttpClient нет необходимости.    

Это сообщение отредактировал(а) COVD - 7.8.2009, 11:57
PM MAIL   Вверх
LSD
Дата 6.8.2009, 16:49 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Leprechaun Software Developer
****


Профиль
Группа: Модератор
Сообщений: 15718
Регистрация: 24.3.2004
Где: Dublin

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



Цитата(COVD @  6.8.2009,  12:53 Найти цитируемый пост)
URLConnection по возможности использует одно физическое соединение при повторных обращениях к одному хосту (если не применять disconnect() после каждого запроса), хотя обьект URLConnection надо каждый раз создавать новый 

Откуда такая информация? И где храниться это соединение, между созданиями URLConnection?


--------------------
Disclaimer: this post contains explicit depictions of personal opinion. So, if it sounds sarcastic, don't take it seriously. If it sounds dangerous, do not try this at home or at all. And if it offends you, just don't read it.
PM MAIL WWW   Вверх
COVD
Дата 6.8.2009, 17:41 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1655
Регистрация: 26.7.2005

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



LSD, спасибо. Моя ошибка :( . Для повторных запросов используется тот же обьект HttpURLConnection. 

PS. Тут действительно как-то непонятно. Для каждого нового запроса создается новый обьект HttpURLConnection, но где-то в глубине хранятся сокетные соединения, которые могут быть использованы повторно. Так сказано в документации. Однако меня смутила строка из документации к методу disconnect() :
Цитата

Indicates that other requests to the server are unlikely in the near future. Calling disconnect() should not imply that this HttpURLConnection instance can be reused for other requests. 

Непонятно, как инстанс HttpURLConnection вообще можно использовать повторно. Это одноразовый обьект, создаваемый для одного запроса. Вторую фразу, наверное, можно понимать как "не думайте, что применение disconnect() позволит повторно использовать обьект". В смысле, что это невозможно никогда.  

PPS

Цитата

Откуда такая информация? И где храниться это соединение, между созданиями URLConnection?


http://java.sun.com/j2se/1.5.0/docs/api/ja...Connection.html

Цитата

Each HttpURLConnection instance is used to make a single request but the underlying network connection to the HTTP server may be transparently shared by other instances. Calling the close() methods on the InputStream or OutputStream of an HttpURLConnection after a request may free network resources associated with this instance but has no effect on any shared persistent connection. Calling the disconnect() method may close the underlying socket if a persistent connection is otherwise idle at that time.


Это сообщение отредактировал(а) COVD - 7.8.2009, 14:32
PM MAIL   Вверх
T_Serg
Дата 7.8.2009, 10:26 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



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

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



Я попробовал сделать как советуете:
Код

            
    
            URL url=new URL("some site");

            URLConnection firstConnection= url.openConnection();
                
            Scanner in=new Scanner(firstConnection.getInputStream());
            FileWriter writer=new FileWriter(new File("inputStream1.html"));

                            
            while (in.hasNext())
            {
                String line=in.nextLine();
                writer.write(line+"\n");
            }
            writer.close();
            
            URLConnection secondConnection= url.openConnection();
            
            in=new Scanner(secondConnection.getInputStream());
            writer=new FileWriter(new File("inputStream2.html"));
                            
            while (in.hasNext())
            {
                String line=in.nextLine();
                writer.write(line+"\n");
            }
            writer.close();


Для некоторых сайтов это подходит. Контент совпадает и генериремые поля тегов совпадают. Для не которых это вариант не подошел (для google.com). Как найти универсальное решение? Может что то можно изменить в исходнике класса URLConnection?

PM MAIL   Вверх
COVD
Дата 7.8.2009, 15:07 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1655
Регистрация: 26.7.2005

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



google.com всего лишь вставляет в страницу уникальные для каждого запроса ключи. 

 
Код

           URL url=new URL("http://www.google.com");

            URLConnection firstConnection= url.openConnection();

            Scanner in=new Scanner(firstConnection.getInputStream());

            List<String> first = new ArrayList();
            while (in.hasNext())
            {
                String line=in.nextLine();                
                first.add(line);
            }
                        

            URLConnection secondConnection= url.openConnection();

            in=new Scanner(secondConnection.getInputStream());

            List<String> second = new ArrayList();
            while (in.hasNext())
            {
                String line=in.nextLine();                
                second.add(line);
            }

            //compare responses
            System.out.println("first.size() = " + first.size());
            for(int i = 0; i < first.size(); i++){
                String firstHTML = first.get(i);
                String secondHTML = second.get(i);
                if(firstHTML.compareTo(secondHTML) != 0){
                    System.out.println("i = " + i);
                    System.out.println("1: "+firstHTML);
                    System.out.println("2: "+secondHTML);
                }
            }


Программа выдает:


Код

i = 0
1: <!doctype html><html><head><meta http-equiv="content-type" ..... window.google={kEI:"6RN8Su7CIpu ......
2: <!doctype html><html><head><meta http-equiv="content-type" ..... window.google={kEI:"6RN8SrTGK5D ......
.....


Запросы разные и в каждом ответе оригинальное значение ключа, а физическое соединение одно. Или не одно. Если сервер не поддерживает keepAlive, то на каждый запрос будет создаваться новое соединение. Но это скрыто от программиста. Программист работает с запросом. 


Необязательно использовать один и тот же обьект URL. Его можно создавать заново для каждого запроса. Если хост запросов одинаковый, то будет использоваться одно shared сокетное соединение (если сервер поддерживает этот режим и соединение не закрывается явно командой disconnect() на клиенте ). 


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


Leprechaun Software Developer
****


Профиль
Группа: Модератор
Сообщений: 15718
Регистрация: 24.3.2004
Где: Dublin

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



Ну там написанно may be, так что я понимаю это implementation specific. Ну и плюс используемая версия протокола.

Имхо если уж так важен keep-alive, то я бы рекомендовал HttpClient, там над этим больше контроля.


--------------------
Disclaimer: this post contains explicit depictions of personal opinion. So, if it sounds sarcastic, don't take it seriously. If it sounds dangerous, do not try this at home or at all. And if it offends you, just don't read it.
PM MAIL WWW   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
Правила форума "Java"
LSD   AntonSaburov
powerOn   tux
  • Прежде, чем задать вопрос, прочтите это!
  • Книги по Java собираются здесь.
  • Документация и ресурсы по Java находятся здесь.
  • Используйте теги [code=java][/code] для подсветки кода. Используйтe чекбокс "транслит", если у Вас нет русских шрифтов.
  • Помечайте свой вопрос как решённый, если на него получен ответ. Ссылка "Пометить как решённый" находится над первым постом.
  • Действия модераторов можно обсудить здесь.
  • FAQ раздела лежит здесь.

Если Вам помогли, и атмосфера форума Вам понравилась, то заходите к нам чаще! С уважением, LSD, AntonSaburov, powerOn, tux.

 
1 Пользователей читают эту тему (1 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | Java: Работа с сетью | Следующая тема »


 




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


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

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